객체를 생성하지 않고도 사용하는 요소로써 클래스 이름을 통해 접근할 수 있다.
객체 참조 변수를 통해서도 사용이 가능하며 딱 하나의 변수만 생성된다.
프로그램 전체에서 딱 하나만 존재하는 값을 저장할 때 사용한다.
static변수나 매개변수를 포함한 지역변수만 사용하는 메서드의 경우 static으로 정의하면 편하게 사용할 수 있다.
// 불가능
System.out.printf("TestClass1.memberA : %d\n", TestClass1.memberA);
TestClass1.method1();
// 가능
System.out.printf("TestClass1.memberB : %d\n", TestClass1.memberB);
TestClass1.method2();
class TestClass1 {
// 멤버 변수
int memberA = 100;
// static 변수
static int memberB = 200;
// 멤버 메서드
public void method1() {
System.out.println("method1 호출");
// 객체를 생성해야지만 사용할 수 있는 메서드 이므로
// 모든 static 요소에 접근할 수 있다.
System.out.printf("memberA : %d\n", memberA);
System.out.printf("memberB : %d\n", memberB);
method2();
}
// static 메서드
public static void method2() {
System.out.println("method2 호출");
// static 메서드는 객체를 생성하지 않아도 호출이 가능하기 때문에
// 객체의 멤버에는 접근이 불가능하다.
System.out.printf("memberA : %d\n", memberA);
System.out.printf("memberB : %d\n", memberB);
method1();
}
}
JVM의 메모리에는 static이 저장되는 영역(Method Area)과 인스턴스가 저장되는 영역(Heap)이 다르고 그 둘이 저장되는 시간 또한 다르다.
Method Area에 저장되는 값은 컴파일 타임에서 저장하며, Heap Area에 저장되는 값은 런타임에 저장된다.
- Static Binding : Compile Time에 메모리에 올라감
- Dynamic Binding : Run Time에 메모리에 올라감
그렇다면 부모에서 정의한 static 메서드(자식에게도 같은 이름의 static 메서드 정의함)는 객체가 생성되기 전에 Method Area에 들어가는거겠죠?
그래서 Overriding을 할 수 없다!
대신 Overriding처럼 보일 수 있는 건 Hiding이라고 한다.
부모 클래스에 있는 static 메소드를 자식 클래스에서 다시 정의하면 부모 클래스에 있는 메모드가 가려지게 된다.
간단하게 말하면 2개의 메서드 모두 사용할 수 있다는 의미이다.
Parent p1 = new Parent();
Parent p2 = new Child();
Child c = new Child();
p1.getTest(); // parent 출력
p2.getTest(); // parent 출력
c.getTest(); // child 출력
class Parent {
static void getTest() {
System.out.println("parent");
}
}
class Child extends Parent {
static void getTest() {
System.out.println("child");
}
}
더이상 변경할 수 없다는 의미