본문 바로가기
[JAVA]/JAVA 기본

내부 클래스를 static으로 선언해야 하는 이유

by 팡펑퐁 2023. 6. 9.
728x90

💡 인텔리제이에서 Inner 클래스를 static 키워드 없이 선언했더니 이런 문구가 나왔다. 내부 클래스를 static으로 선언하라는 이야기인데 왜 static으로 선언하라는 건지 몰라 궁금해서 찾아봤다. 사실 이걸 블로깅할 계획은 없었는데 전혀 모르는 내용이라 짚고 넘어가려고 한다.

 

 

외부 참조 차이

Inner A

  • InnerA는 static이 붙어있지 않은 non-static inner class이다.
  • 일반적인 이너 클래스는 자신을 만들어준 인스턴스에 대해 외부 참조를 갖는다.
  • 이 참조는 이너 클래스가 외부의 멤버를 가져와 사용하지 않아도 암묵적으로 연결한다. 이를 '숨겨진 외부 참조'라고도 한다.
  • 외부에 대한 참조를 가지고 있기 때문에 이너 클래스도 외부의 클래스 자원을 사용할 수 있다는 장점이 있다.
    • 위 클래스의 예시를 보면 외부 클래스의 인스턴스 변수 num을 뜻하는 this num을 가져다 쓸 수 있다.

 

Inner B

  • InnerB는 static이 붙은 static inner class이다.
  • static 이너 클래스는 외부 참조를 하지 않는다.
  • 이 때문에 위의 그림에서 보이는 것과 같이 외부 클래스의 인스턴스를 참조하는 this를 사용할 수 없다.

 

외부 참조의 문제

  • 얼핏 보면 외부 참조가 가능한 non-static inner class가 좋아 보인다.
  • 그러나, 외부 참조는 메모리 누수라는 치명적인 단점이 존재한다.
  • 일반적인 상황이라면 이너 클래스가 외부 클래스을 참조하고 난 후 외부 클래스가 필요 없어질 때 가비지 컬렉션이 외부 클래스를 메모리에서 제거해야 한다.
  • 메서드 호출 용도로 쓰여진 일회용 객체는 가비지 컬렉션의 수거 대상에 포함되기 때문이다.
  • 그런데, 외부 참조로 인해 이너 클래스와 외부 클래스가 연결되어 있어 메모리에서 제거가 되지 않는다.
  • 이 과정이 계속되면 제거되지 않은 메모리가 쌓이게 되어 OutOfMemory를 일으킨다.

 

정리

  • 내부에 클래스를 선언할 때는 static을 사용하여 메모리 누수를 방지하고, static을 사용하고 싶지 않다면 별도의 클래스를 만들자.

 

 

static 클래스의 인스턴스 변수

  • non-static inner class이든, static inner class이든 new 연산자를 이용해 새로운 인스턴스를 2개 만들어도 두 인스턴스는 다른 참조를 가진다. 
  • static이라는 키워드가 클래스에 붙게 되면 인스턴스를 생성하는 방식이 달라지는 것뿐이지 static 클래스가 같은 인스턴스를 만들지는 않는다.
    • static 키워드를 이너 클래스에 붙이면 외부 인스턴스의 도움없이 내부 클래스의 인스턴스를 바로 생성할 수 있다는 차이점만 존재할 뿐이다.

 

 

 

참고

https://siyoon210.tistory.com/141

https://velog.io/@jyleedev/static-inner-class

https://hyokeun0419.tistory.com/49

https://inpa.tistory.com/entry/JAVA-☕-자바의-내부-클래스는-static-으로-선언하자

728x90