익명 내부 클래스(Anonymous Inner Class)란 클래스 이름 없이 선언되는 내부 클래스를 말합니다. 즉, 이름이 없는 내부 클래스이기 때문에 생성자(constructor)를 가질 수 없습니다. 생성자의 이름은 클래스 이름과 동일해야 하기 때문입니다.
익명 내부 클래스는 new 연산자를 사용하여 클래스 정의와 객체 생성을 한 번에 동시에 처리할 수 있다는 점이 큰 특징입니다.
기본 문법
new(argument-list){
// 익명 클래스 본문
}자바 익명 내부 클래스의 3가지 유형
- 클래스를 상속하는 익명 내부 클래스
- 인터페이스를 구현하는 익명 내부 클래스
- 메서드나 생성자의 인자(argument)로 전달되는 익명 내부 클래스
1. 클래스를 상속하는 익명 내부 클래스
이 방식은 new 키워드로 익명 내부 클래스의 객체를 생성하며, 이 객체는 부모 클래스 타입의 참조 변수에 저장됩니다.
예제
class Car {
public void engineType() {
System.out.println("Turbo Engine");
}
}
public class AnonymousClassDemo {
public static void main(String args[]) {
Car c1 = new Car();
c1.engineType();
Car c2 = new Car() {
@Override
public void engineType() {
System.out.println("V2 Engine");
}
};
c2.engineType();
}
}실행 결과
Turbo Engine V2 Engine
위 예제에서 c1은 일반적인 Car 객체이므로 원래 구현된 "Turbo Engine"이 출력되고, c2는 익명 내부 클래스를 통해 engineType() 메서드를 오버라이딩했기 때문에 "V2 Engine"이 출력됩니다.
2. 인터페이스를 구현하는 익명 내부 클래스
이 방식 역시 new 키워드로 익명 내부 클래스의 객체를 생성하지만, 객체가 인터페이스 타입의 참조 변수에 저장된다는 점이 다릅니다.
예제
interface Software {
public void develop();
}
public class AnonymousClassDemo1 {
public static void main(String args[]) {
Software s = new Software() {
@Override
public void develop() {
System.out.println("Software Developed in Java");
}
};
s.develop();
System.out.println(s.getClass().getName());
}
}실행 결과
Software Developed in Java AnonymousClassDemo1$1
출력 결과에서 확인할 수 있듯이, 컴파일러는 익명 내부 클래스에 자동으로 '외부클래스명$번호' 형태의 이름을 부여합니다. 여기서는 AnonymousClassDemo1$1이라는 이름이 생성되었습니다.
3. 인자로 전달되는 익명 내부 클래스
익명 내부 클래스는 메서드나 생성자의 인자로 직접 전달할 수도 있습니다. 코드를 간결하게 만들어 주는 대표적인 활용 방식입니다.
예제
abstract class Engine {
public abstract void engineType();
}
class Vehicle {
public void transport(Engine e) {
e.engineType();
}
}
public class AnonymousInnerClassDemo2 {
public static void main(String args[]) {
Vehicle v = new Vehicle();
v.transport(new Engine() {
@Override
public void engineType() {
System.out.println("Turbo Engine");
}
});
}
}실행 결과
Turbo Engine
위 예제에서는 추상 클래스 Engine을 상속받는 익명 내부 클래스가 transport() 메서드의 인자로 바로 전달되었습니다. 별도의 클래스 파일을 만들지 않고도 필요한 구현을 즉석에서 제공할 수 있습니다.
마무리
익명 내부 클래스는 일회성 구현이 필요한 경우 코드를 간결하게 유지할 수 있는 강력한 기법입니다. 특히 이벤트 리스너나 콜백 처리에 널리 사용되며, 자바 8 이후에는 람다 표현식으로 더욱 간단히 대체할 수 있는 경우도 많습니다. 하지만 여러 추상 메서드를 구현해야 하는 경우나 상태를 유지해야 하는 경우에는 여전히 익명 내부 클래스가 유용합니다.