[자바] static과 static final

2021. 12. 17. 17:51Java

배우고 이해한 내용을 정리하는 글로써 틀린 부분이 있을 수 있습니다. 잘못된 점이 있으면 댓글로 남겨주시면 감사하겠습니다ㅎ.ㅎ


우선 static에 대해 간단히 알아보자, static 키워드가 사용된 전역변수나 메소드는 컴파일 과정 중에 정적으로 바인딩되어 static 메모리에 할당된다. 따라서 프로그램이 실행될 때 static메모리에 할당되어 있다가 프로그램이 종료시에 값이 제거된다. 이와 반대로 지역변수의 경우 메소드의 '{'가 시작되는 시점에서 메모리에 할당되고 '}'를 만나서 메소드가 종료가 되면 지역변수의 값도 제거된다.

 

이처럼 static은 컴파일시에 생성되어서 종료시까지 계속 재사용할 수 있다. 스프링의 대표적인 개념인 싱글톤 패턴이 static 키워드를 통해 객체 관리가 되는 이유이다. new 키워드를 사용해서 인스턴스를 생성하게 될경우 같은 객체의 인스턴스라고 할지라도 new 키워드를 통해 인스턴스를 생성할 때마다 할당되는 메모리의 주소 값은 다르다. new 키워드를 통해 생성되는 인스턴스는 힙 영역에 메모리가 할당되며 이를 정의한 변수(stack에 할당)와 연결되어 있으며 변수와 연결이 없을 경우 가비지컬렉터(garbage collector)에 의해 메모리에서 제거된다. 에초에 컴파일시에 메모리가 할당되어 프로그램이 끝나기 전까지 메모리에 남아 있는 static과는 메모리의 영역 및 관리가 다르다. 자바 메모리 사용에 대해 이해가 되지 않는다면 메모리 관련해서 포스팅했던 글이 있으니 참고해봐도 좋다. 

 

그럼 이제 포스팅의 목적인 static과 static final의 차이에 대해서 알아보자, final 키워드에 간단하게 정리하자면 final 키워드는 상수, 메소드, 클래스 3가지 경우에 사용할 수 있다. 

 

final 키워드의 사용

1) 상수

public class Test {
  final String STUDY ="java";
  
  STUDY = "spring"; // 에러발생
  System.out.println(STUDY);
}

final 키워드를 상수 정의용으로 사용할 경우, 클래스의 멤버변수를 final 키워드와 함께 한 번 값을 정의 했다면 상수값을 직접 수정하지 않는 한 다시 값을 수정할 수 없다. 즉, 한 번 정해논 값을 계속 사용하는 상수의 용도로 사용한다.

 

2) 메소드

public Test {
	public final void test1() {}    
}

public Test2 extends Test {
	//@Override
	//public final void test1() {} 오버라이딩 불가능
}

메소드에 final 키워드를 사용할 경우에, 해당 메소드가 정의된 클래스를 상속받은 자식 클래스에서 final키워드가 붙어있는 메소드를 재정의하여 사용하기 위해서 오버라이딩을 하고 싶어도 할 수 없다. 위의 상수예제와 마찬가지로 한 번 값을 정의한 final의 메소드는 값을 재정의할 수 없다.

 

3) 클래스

final class Test {}

public class Test2 extends Test {} //상속 불가능

final 키워드를 통해 생성한 클래스는 상속이 불가능하다. 

 

즉, final 키워드를 사용해서 값이 정의될 경우 재정의해서 사용할 수 없다.  그럼 static final을 사용하면 뭐가 다를까? 

위에서 설명했듯이 static을 이용해서 변수를 선언할 경우 해당 변수는 객체생성 없이 클래스명을 통해 접근이 가능해지며 생성된 값은 static메모리에 할당되므로 공통된 값을 사용하게 된다. 이러한 static에 final 키워드를 사용하게 된다면 하나의 공통된 값을 사용하는 재정의할 수 없는 값이 된다. 즉, static final int ARG = 1; 이라고 정의할 경우 공용으로 사용할 수 있으며 값을 재할당할 수 없는 상수가 된다.