static은 정적 변수라고도 하며, 클래스 수준에서 메서드, 변수 ,클래스를 선언할 때 같이 사용된다.
❓ Static의 특징
일반적으로 클래스를 설계하고 그 안에 멤버변수나 멤버메서드를 사용하기 위해서는 new 연산자를 활용하여 인스턴스화하여 접근해야 가능하다.
그러나 static은 모든 클래스들에게 공유되는 특성을 가지며, 따로 인스턴스화 하지않고도 클래스명을 통해 접근이 가능하다.
🔍 Static 사용
◾ static 선언 방법
public static 변수 or 메서드 or 클래스
public static void main(String[] args) {}
👉 main 외부에서 생성하도록 하며 변수,메서드,클래스에 적용 가능하다. ◾ Static이 없을 경우에 접근
//파일명 : Person
public class Person{
String name = "홍길동";
int age = 10;
}
//파일명 : Main
public static void main(String[] args) {
//바로 person 호출 불가능
System.out.println(Person.name);
//인스턴스 생성 후 person 호출
Person p = new Person();
System.out.println(p.name);
}
◾Static 적용
//파일명 : Person
//name 에 static 적용
public class Person{
static String name = "홍길동";
int age = 10;
}
//파일명 : Main
public static void main(String[] args) {
//바로 person 호출 가능
System.out.println(Person.name);
//age는 불가능
System.out.println(Person.age); ❌
}
🤔 Static 과 non_Static의 방식에 어떤 차이가 있는걸까?
우선 파일이 실행 될 때 순서부터 살펴보자
1️⃣ 자바 프로그램이 실행되면 컴파일러를 통하여 .java 파일을 .class 파일로 변환
2️⃣ JVM이 필요한 클래스를 메모리에 로드한다 (main을 가장 먼저 찾아 로드)
❗이때 Static과 non_Static의 차이
👉 Static
클래스를 메모리에 로드할 때 Static도 동시에 메서드, 클래스 영역에 로드 된다.
👉 non_Static
new 연산자를 통해서 인스턴스가 생성될 시에 Heap 영역에 로드 된다.
🔍 차이점을 예제로 확인
//파일명 : Person
public class Person{
static String name = "홍길동";
int age = 10;
}
//파일명 : Main
public static void main(String[] args) {
Person p1 = new Person();
Person p2 = new Person();
p2.name= "짱구";
p2.age = 100;
System.out.printf("p1의 이름:%s | 나이:%d \n",p1.name,p1.age);
System.out.printf("p2의 이름:%s | 나이:%d",p2.name,p2.age);
}
👉 Static이 붙은 name 변수는 값이 같이 변경되고 non_Static인 age 변수는 개별적으로 변경 된다.
❓ 이런 결과가 나오는 이유
non_Static은 인스턴스가 생성될 때 해당 인스턴스에 속하며 힙 메모리에 저장된다.
따라서 여러 인스턴스마다 개별적으로 non_static 변수 값이 관리 되기 때문에 p2의 age를 바꿀 경우 p1의 값까지 변경되지 않고 p2만 변경 된다. 반면 Static은 클래스가 로드될 시 클래스 영역에 로드 된다.
따라서 인스턴스를 각각 생성하여 값을 변경한다하여도 변수 자체가 이미 클래스에서 모든 인스턴스에게 공유되고있기 때문에 하나의 인스턴스를 통해 값을 바꾼다고 하여도 바뀐 값이 다른 객체에도 전부 공유가 된다.