Java Anonymous Class (익명 클래스)

 

익명 클래스란 무엇인가?

자바에서 익명 클래스(Anonymous Class)란 이름이 없는 클래스이다. 보통 일회성으로 어떤 기능을 빠르게 구현하고 싶을 때 사용한다. 특정 인터페이스를 구현하거나 클래스를 상속할 필요는 있지만, 굳이 이름 있는 클래스를 따로 정의하기에는 번거로운 경우에 주로 쓰인다.

익명 클래스는 다음과 같은 형식으로 작성한다:

Button btn = new Button();
btn.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("버튼 클릭됨");
    }
});

위 코드에서 ⟨⟨OnClickListener⟩⟩를 구현하는 클래스의 이름이 없다는 점에 주목할 수 있다. 이게 바로 익명 클래스의 핵심이다. 즉석에서 구현체를 만들어서 사용하는 방식이다.


익명 클래스의 특징과 장단점

익명 클래스는 다음과 같은 특징을 가진다:

  1. 이름이 없다
    클래스 이름 없이 곧바로 선언과 동시에 객체를 생성한다. 때문에 재사용은 불가능하다.
  2. 한 번만 사용할 구현체에 적합하다
    예를 들어 ⟨⟨Runnable⟩⟩, ⟨⟨Comparator⟩⟩, ⟨⟨ActionListener⟩⟩ 등을 단발성으로 구현할 때 주로 사용된다.
  3. 외부 변수 참조 시 final 또는 effectively final이어야 한다
    지역 변수는 수정이 불가능하며, 내부에서 참조만 가능하다.

이러한 특성으로 인해 다음과 같은 장단점이 생긴다:

 

장점

  • 클래스를 별도로 선언하지 않아도 되므로 코드가 간결해진다.
  • 즉석에서 구현할 수 있어 빠르게 테스트하거나 일회성 로직 작성에 유용하다.

단점

  • 가독성이 떨어질 수 있다
    코드 안에 클래스 정의와 로직이 동시에 들어가므로, 특히 중첩되면 읽기 어려워진다.
  • 디버깅이 어렵다
    익명 클래스는 이름이 없기 때문에 로그나 스택트레이스에서 식별이 어렵다.
  • 람다 표현식이 등장하면서 사용 빈도가 줄었다
    Java 8부터는 익명 클래스의 대부분의 쓰임이 람다로 대체 가능하다.

익명 클래스 사용 예시

아래는 자바에서 가장 대표적으로 익명 클래스가 쓰이는 예 중 하나인 ⟨⟨Runnable⟩⟩ 인터페이스 구현 예시이다:

Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("스레드 실행 중...");
    }
});
thread.start();

이처럼 ⟨⟨Runnable⟩⟩은 추상 메서드 ⟨⟨run()⟩⟩ 하나만 가진 인터페이스이므로, 익명 클래스로 바로 구현해 쓸 수 있다.


또한 컬렉션 정렬 시 ⟨⟨Comparator⟩⟩를 익명 클래스로 구현하는 방식도 자주 등장한다:

List<String> list = Arrays.asList("banana", "apple", "cherry");
Collections.sort(list, new Comparator<String>() {
    @Override
    public int compare(String a, String b) {
        return b.compareTo(a); // 내림차순
    }
});

이 방식은 Java 8 이후에는 람다 표현식으로 간결하게 바뀌었지만, 익명 클래스는 여전히 람다로 표현할 수 없는 복잡한 구조를 구현할 때 사용된다.
예를 들어 여러 메서드나 상태를 갖는 경우, 익명 클래스는 람다보다 더 유리하다.