본문 바로가기

지식/Java

[Java] 자바 static, final , static final 차이

오늘 MyBatis를 적용하면서 static관련 에러 메세지를 보게 되었습니다.

기초적인 에러라고 생각하고 고쳐야지 하면서 생각을 하는데... 에러를 고치는데 많은 시간을 쓰게 되고 한번 정리를 해야겠다 생각하게 되었습니다.

 

 

- static 이란?

정적, 고정된의 의미를 갖고 있습니다.

static 키워드를 사용하여 변수, 메소드를 만들 수 있습니다. 이들을 정적 변수, 정적 메소드라고도 하며 이 둘을 합쳐 정적 멤버 혹은 클래스 멤버라고도 합니다.

말 그대로 static 변수와 메소드는 객체(인스턴스)에 소속된 멤버가 아닌 클래스고정된 멤버입니다.

(클래스로더가 클래스를 로딩해서 초기화할 때 함께 초기화됩니다.)

 

- static 멤버 생성

이전의 자바 컴파일 과정을 설명한 글을 쓰면서 나온 개념으로 JVM의 런타임 데이터 영역을 되돌아보면,

힙(Heap), 메서드영역(Method Area)영역이 있었습니다.

a. 메서드 영역 : 클래스 정보, 변수 정보, static으로 선언한 변수가 저장 (모든 스레드가 공유)

b. 힙 영역 : 동적으로 생성된 객체가 저장되는 영역으로 GC의 대상이 되는 공간 (모든 스레드가 공유)

 

원래의 객체를 만들면서 생성된 변수나 메소드는 GC의 영향을 받는 힙영역에 올라가야 하지만,

static을 적용한 멤버는 메서드 영역에 올라가게 됩니다.

 

static영역에 할당된 멤버는 모든 객체가 공유하고 하나의 멤버를 어디서든지 참조할 수 있는 장점이 있지만,

GC의 관리 영역 밖에 존재하기에 static 멤버들은 프로그램 종료시까지 메모리가 할당된 채 존재하게 됩니다.

그렇기에 static을 너무 많이 사용하면 시스템 성능에 악영향을 줄 수 있습니다.

 

- final 이란?

final은 크게 상수, 메서드, 클래스 3가지 경우에 사용할 수 있습니다.

 

1. 상수에서의 final

final int a;

값을 한번 저장하고 다시는 바꾸지 않을 때 사용합니다.

즉, 변수를 상수로 만드는 용도로 사용하게 됩니다.

 

2. 메서드에서의 final

class test1 {
    public final void method1(){   }
}
public class main extends test1
{      
    public void method1(){   } //error: class, interface, or enum expected
}

오버라이딩을 못하게 만들고 싶을 때 사용합니다.

즉, 다른 클래스가 method1을 extends한다면 에러가 발생합니다.

 

3. 클래스에서의 final

final class class1{ }

class class2 extends class1 { }//error: cannot inherit from final main.class1

상속을 못하게 만들고 싶을 때 사용합니다.

즉, final 키워드를 사용한 클래스는 객체를 생성할 수 없습니다.

 

 

- static final 이란?

static은 클래스 변수입니다. final은 상수 입니다.

이 둘을 합치면?

객체(인스턴스)가 아닌 클래스에 존재하는 단 하나의 상수입니다.

즉, 객체마다 값이 바뀌는 것이 아닌 클래스에 존재하는 상수로 선언과 동시에 초기화를 해주어야하는 클래스 상수입니다.

 

 

 

 

참고 

https://blog.naver.com/goddlaek/220889229659

https://wjddntjr555w.tistory.com/41

https://coding-factory.tistory.com/524