
이번 글에서는 Backend / OOP logic in Java 영역에서 자주 등장하는 익명 클래스(Anonymous Class)를 정리한다. 추상 클래스(Abstract Class)와 함께 사용할 때 어떤 의미를 가지는지, 그리고 “일회성 구현”이 왜 필요한지 구조 중심으로 이해해보자.
익명 클래스는 “이름 없는 클래스”다. 보통 클래스는 파일로 분리해서 선언하지만, 익명 클래스는 객체를 생성하는 순간 그 자리에서 클래스를 정의한다.
즉, 다음 구조다.
핵심 포인트는 이거다.
“한 번만 쓰는 구현체라서, 굳이 클래스 파일을 따로 만들지 않는다.”
먼저 일반적인 방식이다.
그 다음, 익명 클래스 방식이다.
둘 다 업캐스팅(부모 타입 참조) 구조를 사용한다는 점이 중요하다.
먼저 추상 클래스는 “구현 규칙(메서드 시그니처)”만 정의하고, 실제 동작은 하위 클래스에게 맡긴다.
public abstract class AbstractTest {
public abstract void showData(String data);
public abstract void add(int num1, int num2);
}
여기서 AbstractTest는 객체를 직접 생성할 수 없고, 반드시 메서드를 구현한 하위 클래스가 필요하다.
추상 클래스를 상속받아 별도의 구현 클래스를 만든다.
public class AbstractTestImpl extends AbstractTest {
@Override
public void showData(String data) {
System.out.println("data: " + data);
}
@Override
public void add(int num1, int num2) {
System.out.println("num1: " + num1);
System.out.println("num2: " + num2);
}
}
그리고 객체를 생성할 때는 업캐스팅 구조를 사용한다.
AbstractTest abstractTest = new AbstractTestImpl();
abstractTest.showData("gildong");
abstractTest.add(10, 20);
이 방식은 재사용 가능한 구현에 적합하다. 여러 곳에서 같은 로직을 쓰거나, 역할이 명확한 클래스라면 이렇게 분리하는 게 맞다.
이번에는 구현 클래스를 따로 만들지 않고, 객체 생성과 동시에 구현한다.
AbstractTest abstractTest2 = new AbstractTest() {
@Override
public void showData(String data) {
System.out.println("익명");
System.out.println("data: " + data);
}
@Override
public void add(int num1, int num2) {
System.out.println("익명");
System.out.println("num1: " + num1);
System.out.println("num2: " + num2);
}
};
abstractTest2.showData("gilseo");
abstractTest2.add(10, 20);
이 코드의 의미는 다음과 같다.
두 방식 모두 본질은 동일하다.
부모 타입(AbstractTest) 참조 변수에 자식 객체를 담는 업캐스팅
차이점은 “구현 클래스가 파일로 존재하느냐” vs “실행 시점에 즉석에서 만들어지느냐”이다.
컴파일 시, 익명 클래스도 내부적으로는 다음과 같은 형태로 처리된다.
예를 들어:
이런 경우, 클래스 파일을 하나 더 만드는 것보다 익명 클래스가 훨씬 간결하다.
따라서 기준은 명확하다.
“짧고 일회성 → 익명 클래스”
“여러 곳에서 재사용 → 일반 구현 클래스”
익명 클래스는 자바 8 이후 람다(lambda)로 더 간결해질 수 있다. 단, 추상 메서드가 하나뿐인 인터페이스일 때만 람다로 대체 가능하다.
즉:
이 구분이 실무에서 매우 중요하다.
익명 클래스는 단순한 문법이 아니라, “구현을 구조적으로 분리하면서도, 불필요한 클래스 파일 생성을 줄이기 위한 OOP 설계 도구”라는 점이 인상 깊었다. 특히 콜백, 전략 패턴, 이벤트 처리처럼 “동작을 객체로 넘기는 구조”에서 익명 클래스는 코드의 의도를 가장 직관적으로 드러내는 방법이다.