자바는 클래스 안에 클래스를 사용할 수 있다. 이런 중첩 클래스에는 크게 2가지로 나눠 볼 수 있다.

중첩 클래스는 감싸주고 있는 클래스의 멤버로 간주.
중첩 클래스는 인스턴스 변수와 외부 클래스의 인스턴스 메서드에 접근 가능.
관련된 클래스들이 서로 가까이 위치하여 코드 가독성을 향상.
캡슐화.
한 곳에서만 사용되는 클래스를 중첩 클래스로 정의함으로써 코드의 의도를 더 명확하게 전달.
외부클래스의 인스턴스화 없이 인스턴스화 할 수 있으며, 외부 클래스의 Non-static 멤버에는 접근이 불가함.
public class Outer {
private int hide = 1;
public int pub = 2;
private static int staticInt = 3;
public static class Inner{
public void print(){
System.out.println(staticInt);
System.out.println(pub); //compile error
System.out.println(hide); //compile error
}
}
}
겉보기에는 static 예약어가 붙냐 안붙냐의 차이이다.
public class Outer {
private int hide = 1;
public int pub = 2;
private static int staticInt = 3;
public class Inner{
public void print(){
System.out.println(staticInt);
System.out.println(pub);
System.out.println(hide);
}
}
public static void main(String[] args) {
Outer outer = new Outer();
Inner inner = outer.new Inner();
inner.print();
}
}
static이 없는 중첩 클래스는 외부클래스의 private 멤버까지 접근이 가능하다. 하지만 중첩 클래스를 사용하려면 외부클래스를 통해 생성해야한다.
익명클래스 역시 중첩 클래스로 분류가 된다.
public class Outer {
public interface Anonymous {
public void print();
}
public static void main(String[] args) {
Anonymous anonymous = new Anonymous() {
@Override
public void print() {
System.out.println("익명 클래스입니다.");
}
};
anonymous.print();
}
}
구현체가 없는 Interface를 직접 new생성자로 인스턴스화를 시키면 구현체를 만들어 줘야한다. 이때 익명클래스로 필요한 구현체 클래스를 생성할 수 있다.
Static Nested Class는 자신을 인스턴스화 하기 위해서 외부클래스의 객체가 필요하지 않지만 Non-static Nested Class는 외부클래스의 객체가 필요하다. 즉, static의 차이로 외부참조 필요성의 차이가 있다.
외부참조가 있다는 것은 가비지 컬렉션이 인스턴스 수거를 하지 못하여 메모리 누수가 생길 수 있다는 말이다.
때문에 가급적이면 Static Nested Class를 사용하는 것을 권장하며, Non-static Nested Class를 사용한다면 일반 Class로의 전환을 생각해보는 것을 추천 한다.
한 줄평 : 웹 개발할 때 static 중첩클래스는 DTO, VO클래스에서 많이 사용했었는데 확실히 코드구조가 이해하기 좋았다.