람다 vs 익명 클래스

Jun·2025년 5월 19일

고급 자바

목록 보기
5/7

자바 람다 표현식 vs 익명 클래스

자바에서 기능 구현이나 일회성 객체 생성 시 자주 사용되는 두 방식, 익명 클래스(Anonymous Class)와 람다 표현식(Lambda Expression)을 비교하여 명확히 이해해 보자.


1. 문법적 차이

익명 클래스

Button button = new Button();
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        System.out.println("버튼 클릭");
    }
});
  • 반드시 new 인터페이스명() {} 형태로 작성해야 함
  • 명시적으로 메서드를 오버라이딩 해야 함
  • 별도의 클래스 생성

람다 표현식

Button button = new Button();
button.setOnClickListener(v -> System.out.println("버튼 클릭"));
  • -> 연산자를 사용하여 간결하게 표현
  • 함수형 인터페이스(메서드 1개)만 구현 가능

2. 코드의 간결성

  • 익명 클래스: 코드가 장황하며 불필요한 구문이 많음
  • 람다 표현식: 불필요한 코드를 최소화하여 핵심 기능만 명시적으로 표현

3. 상속 및 상태 관리

익명 클래스

  • 여러 메서드를 가진 인터페이스나 클래스를 상속하거나 구현 가능
  • 내부 상태(필드)를 유지할 수 있음

람다 표현식

  • 오직 하나의 메서드를 가진 함수형 인터페이스만 구현 가능
  • 내부 상태(필드) 유지 불가능 (함수로서만 동작)

4. 호환성

  • 익명 클래스: 자바 초기 버전부터 사용 가능
  • 람다 표현식: 자바 8 이후 버전부터 사용 가능

5. this 키워드의 의미

익명 클래스

  • this: 익명 클래스 자체의 인스턴스를 참조

람다 표현식

  • this: 람다를 선언한 외부 클래스의 인스턴스를 참조

예시 코드

public class OuterMain {
    private String message = "외부 클래스";

    public void execute() {
        Runnable anonymous = new Runnable() {
            private String message = "익명 클래스";
            @Override
            public void run() {
                System.out.println("익명 클래스 this.message: " + this.message);
            }
        };

        Runnable lambda = () -> System.out.println("람다 this.message: " + this.message);

        anonymous.run();
        lambda.run();
    }
}

실행 결과

익명 클래스 this.message: 익명 클래스
람다 this.message: 외부 클래스

6. 캡처링(Capturing)

  • 공통점: 외부 로컬 변수는 final 또는 사실상(final) 변수만 접근 가능

사실상(final) 변수란?

  • final로 선언하지 않았으나 값을 변경하지 않은 변수 (effectively final)

예시 코드

final int final1 = 10;
int final2 = 20; // 사실상 final
int changedVar = 30; // 값 변경되는 변수

Runnable lambda = () -> {
    System.out.println(final1); // 가능
    System.out.println(final2); // 가능
    // System.out.println(changedVar); // 컴파일 오류
};

changedVar++;

7. 내부 동작 방식

익명 클래스

  • 컴파일 시 별도의 클래스 파일(OuterClass$1.class) 생성
  • JVM에서 별도 클래스 로딩 과정 필요

람다 표현식

  • 컴파일 시 별도 클래스 파일 미생성
  • 런타임 시 동적으로 필요한 코드 처리(invokeDynamic 메커니즘 활용)
  • 메모리 효율성 우수(미미한 차이)

📌 정리

  • 대부분의 경우 간결한 코드와 높은 가독성 측면에서 람다 표현식이 더 좋다.
  • 여러 메서드를 구현해야 하거나 내부 상태를 관리해야 할 때는 익명 클래스가 적합하다.
  • 두 가지 모두 사용 가능할 경우 일반적으로 람다 표현식을 권장한다.

상황과 목적에 맞게 익명 클래스와 람다 표현식을 적절히 선택하여 활용하자

profile
꾸준하게

0개의 댓글