Static과 Final

Static

public class MyClass {
	public static void foo1() {}
    public void foo2() {}
}

위 2개의 메서드를 사용하고 싶을 때의 차이를 이해하면 된다.
다른 점은 static이 붙고 안붙고의 차이다.

첫번째 foo1MyClass.foo1();으로 사용할 수 있고,
두번째 foo2MyClass myClass = new MyClass();로 인스턴스를 생성해준 후, myClass.foo2();로 사용할 수 있다.

static은 보통 모든 인스턴스에서 공통으로 사용하는 것에 붙는다.
static 변수, static 메소드는 인스턴스를 생성(new)하지 않아도 이미 클래스가 메모리에 올라갈 때 생성되기 때문에, 모든 인스턴스에서 공통적으로 사용할 수 있기 때문이다.

여기서 주의해야 할 점은 static 메서드의 경우 인스턴스 변수를 사용할 수 없다는 것이다.

예를 들어,

int a, b;

static int add () {
	return a+b;
}

이런 식으로 사용이 불가하다는 것이다.

왜냐하면 int a,b는 인스턴스 변수이므로 인스턴스가 반드시 존재해야지만 사용할 수 있는데, static메서드는 인스턴스 생성 없이 호출이 되므로 메서드만 호출되고, 인스턴스는 생성이 되지 않아 int a,b는 없는 변수가 될 수 있기 때문이다.

이 때, JVM의 메모리 구조를 살펴보면서 좀 더 직관적으로 이해해보자.

Java 메모리 구조

Java는 JVM(Java Virtual Machine)이라는 가상 시스템에서 실행된다. 우리가 .java 파일로 코딩을 하면 이 파일을 자바 컴파일러(javac)가 JVM이 이해할 수 있는 bytecode로 바꾸어서 .class 파일을 생성해준다.

그러니까 javac는 일종의 번역가인 셈이다.

.class 파일은 JVM만 설치되어 있으면 OS(Windows, Mac, Linux)에 관계없이 실행될 수 있다.

이렇게 번역된 .class 파일은 JVM 안에서 위의 그림처럼 나뉘어져서 관리된다.

한 눈에 봐도 알 수 있듯이, Method Area에 우리가 아까 본 Static 메서드와 변수가 저장된다. 아까

static 변수, static 메소드는 인스턴스를 생성(new)하지 않아도 이미 클래스가 메모리에 올라갈 때 생성되기 때문에

라고 언급했는데, 이게 바로 그 말이다.

그렇기 때문에 생명주기(Lifecycle)도 클래스와 똑같다.

반대로 일반 메서드의 경우, 객체를 생성해야 하는데, new를 해주어 객체를 생성하면 Heap 영역에 객체가 만들어진다. 그 후에 객체를 통해서 접근하여 메서드를 호출할 수 있다.

Final

흔히, 상수라고 하는 것들이다.
final이 붙으면 오버라이딩을 할 수 없게 되고, 자손클래스를 정의하지 못하게 된다.
일반적으로 선언과 초기화를 동시에 하고, 인스턴스 변수일 경우에는 생성자에서 초기화를 할 수 있다.

선언과 초기화를 동시에 하지 않고 생성자에서 하게 되면, 각 인스턴스마다 final 변수들이 각각 다른 값을 갖도록 할 수 있다.

좋은 웹페이지 즐겨찾기