[Java/TIL] InnerClass 사용시 static선언을 권장하는 이유

resilient

·

2024. 3. 17. 15:09

728x90
반응형

 

인텔리제이와 같은 IDE에서 내부 클래스를 선언하여 개발하는 경우 아래와 같은 경고 메시지를 볼 수 있습니다.

 

메시지의 내용은 내부 클래스를 인스턴스가 아닌 static으로 선언하라는 경고문이죠.

 

Inner class may be 'static'

 

0. 왜 static으로 선언해야 할까요?

 

그 이유는 inner 클래스는 inner static 클래스보다 메모리를 더 필요로 하고, 속도도 더 느리고, 외부 클래스가 GC(Garbage Collector) 대상에서 빠지게 되는 현상을 야기 시킴으로써 메모리 관리가 안될 수도 있기 때문입니다.

 

지금부터 구체적으로 살펴보겠습니다.

 

1. 내부 클래스(Inner Class)란?

 

먼저 내부 클래스에 대해서 요약해서 알아보도록 하죠.

 

내부 클래스란 하나의 클래스 내부에 선언된 클래스를 의미합니다.

맨 위의 예시 코드를 보면 알 수 있듯이 PinServiceImpl 클래스 안에 CustomPinServiceImpl 클래스가 있는 형태죠.

 

내부 클래스는 일반적으로 외부 클래스와 내부 클래스가 서로 긴밀한 관계가 있거나, 하나의 클래스 또는 메서드에서만 사용하는 클래스 일 때 사용합니다.

 

2. 내부 클래스(Inner Class)의 장점은?

 

2-1. 클래스를 논리적으로 그룹화 할 수 있다.

 

다른 외부 클래스들과 관계가 거의 없는 클래스이면서, 하나의 특정 클래스와만 관계를 맺고 있다면 내부 클래스로 작성할 수 있습니다.

 

이와 같은 경우는 유지보수나 이해도 측면에서 편리해지게 되죠.

 

2-2. 강력한 캡슐화

 

(캡슐화는 관련이 있는 변수와 함수를 하나의 클래스로 묶고 외부에서 쉽게 접근하지 못하도록 은닉하는게 핵심입니다.)

 

내부 클래스에 private 접근 제어자를 적용하면 클래스를 내부로 숨길 수 있게 됩니다.

 

캡슐화를 통해 외부에서의 접근을 차단하면서 내부 클래스에는 외부 클래스의 멤버들을 제약 없이 접근 할수 있어 구조적이고 안전한 프로그래밍이 가능해지게 되죠.

 

캡슐화 예시

 

3. 내부 클래스(Inner Class)를 static으로 선언해야 하는 이유

 

이제 이번 포스팅의 목적인 내부 클래스를 static으로 선언해야 하는 이유에 대해서 살펴보겠습니다.

 

3-1. 내부 클래스(Inner Class)는 외부 참조를 하기 때문에 암묵적인 참조관계가 유지된다.

 

내부 클래스가 static으로 선언되지 않으면 각 내부 클래스 객체가 외부 클래스의 인스턴스에 대한 암묵적인 참조를 유지합니다.

 

이는 내부 클래스의 인스턴스가 생성될 때마다 해당 참조를 유지하기 위해 추가적인 메모리 및 시간이 소비될 수 있음을 의미하죠.

 

일반적으로, 내부 클래스가 static으로 선언되면 외부 클래스의 인스턴스에 대한 참조를 유지하지 않으며, 따라서 내부 클래스의 인스턴스 생성에 더 적은 시간과 메모리가 소비됩니다.

 

이는 내부 클래스 객체가 외부 클래스의 인스턴스와 독립적으로 존재할 수 있기 때문입니다.

 

하지만 내부 클래스에서 외부 클래스의 객체에 많은 참조를 요구한다면, static으로 사용하지 않고 사용하는 편이 더 나을 수도 있겠죠?

 

static유무에 따른 참조 유무

 

3-2. 외부 참조로 인한 메무리 누수 현상 발생

 

내부 클래스가 외부 클래스를 외부 참조 함으로써 외부 클래스가 필요없어지고 내부 클래스만 남아있는 경우를 살펴보겠습니다.

 

사용하지 않는 외부 클래스를 GC 대상으로 삼아 메모리에서 제거해야 하지만 외부 참조로 내부클래스와 연결되어 있으면 메모리에서 GC가 제거 대상으로 인식하지 않습니다. 때문에 메모리에서 제거가 되지 않고 메모리 누수가 발생하게 되는 것이죠.

 

4. 정리

 

정리 해보면, 내부 클래스를 선언해야 할 경우 static 키워드를 함께 선언해줘야 합니다.

 

아닐 경우 외부 참조 현상이 일어나기 때문에 내부 클래스 인스턴스를 생성하기 위해 우선적으로 만들었던 외부 클래스 인스턴스가 GC 수거가 안되기 때문입니다.

 

따라서 내부 클래스가 외부 클래스의 멤버를 가져와 사용하는 경우가 아니라면, 반드시 static을 붙이는게 좋습니다.

 

감사합니다.

 

반응형