JAVA - 람다 vs 익명 클래스 완전 정리
개요
자바에서 익명 클래스(Anonymous Class)와 람다 표현식(Lambda Expression)은 둘 다 일회성 로직을 간결하게 구현할 수 있는 방법이다. 하지만 문법 구조, 내부 동작, 상태 관리, 가리키는 this 등에서 뚜렷한 차이가 존재한다. 이 글에서는 두 방식의 차이를 정확히 비교하며 언제 어떤 방식이 더 적합한지 예제 중심으로 설명한다.
1. 문법 차이
익명 클래스
Button button = new Button();
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
System.out.println("버튼 클릭");
}
});
- new 인터페이스() 형태로 바로 구현
- 메서드를 반드시 오버라이드해야 함
- 클래스가 생성되어 컴파일 시 실제 .class 파일이 만들어진다
람다 표현식
Button button = new Button();
button.setOnClickListener(v -> System.out.println("버튼 클릭"));
- 함수형 인터페이스를 대상으로 > 문법 사용
- 구현할 메서드가 하나일 경우 간결하게 표현 가능
- 메서드 본문만 집중적으로 작성 가능
2. 코드 간결성
항목 | 익명 클래스 | 람다 표현식 |
코드 길이 | 길고 장황함 | 매우 짧고 직관적임 |
반복 작성 시 | 불필요한 오버라이드 반복 필요 | 핵심 로직만 작성 가능 |
람다는 특히 이벤트 리스너나 간단한 변환 작업 등에 적합하다.
3. this 키워드의 의미
- 익명 클래스의 this: 해당 익명 클래스 인스턴스를 가리킴
- 람다의 this: 외부 클래스를 가리킴
public void execute() {
Runnable anonymous = new Runnable() {
@Override
public void run() {
System.out.println("익명 클래스 this: " + this.getClass());
}
};
Runnable lambda = () -> {
System.out.println("람다 this: " + this.getClass());
};
anonymous.run();
lambda.run();
}
실행 결과
- 익명 클래스 → OuterMain$1
- 람다 → OuterMain
람다는 자신만의 컨텍스트가 없으며 외부 클래스와 동일한 this를 공유한다.
4. 상태(State) 보존 가능성
익명 클래스
Runnable anonymous = new Runnable() {
private int count = 0;
@Override
public void run() {
count++;
System.out.println("count = " + count);
}
};
- 내부 상태 필드 보존 가능
- 상태 기반 로직 구현에 적합
람다
Runnable lambda = () -> {
// 상태 필드 선언 불가
System.out.println("stateless 실행");
};
- 람다는 상태를 가질 수 없음
- 순수 함수처럼 stateless 방식으로 동작
5. 외부 변수 캡처
int base = 10; // 사실상 final
Runnable lambda = () -> {
System.out.println(base); // OK
};
- 익명 클래스와 람다 모두 외부 지역 변수 참조 가능
- 단, 해당 변수는 반드시 final 혹은 사실상 final이어야 함
- 중간에 값을 바꾸면 컴파일 에러 발생
6. 내부 동작 원리
항목 익명 클래스 람다 표현식
클래스 생성 | 컴파일 시 새로운 클래스 파일 생성 | 클래스 파일 없음 |
처리 방식 | 컴파일 단계에서 클래스 정의 | invokeDynamic을 통한 런타임 처리 |
메모리 효율 | 상대적으로 낮음 | 상대적으로 높음 |
람다는 메서드로 치환된 형태를 런타임에서 동적으로 처리하기 때문에 메모리 측면에서 이점이 있으나, 실제 체감할 정도는 아니다.
7. 사용 가능 자바 버전
항목 | 익명 클래스 | 람다 표현식 |
최소 지원 버전 | Java 1.1 이상 | Java 8 이상 |
레거시 시스템에서는 람다 사용이 불가능할 수 있으므로 주의가 필요하다.
8. 선택 기준
조건 | 추천 방식 |
상태가 필요한 경우 | 익명 클래스 |
복잡한 인터페이스 구현이 필요한 경우 | 익명 클래스 |
간결하고 가독성이 중요한 경우 | 람다 표현식 |
단일 메서드만 구현하는 경우 | 람다 표현식 |
최종 정리
- 문법, 가독성, 목적에 따라 람다 vs 익명 클래스는 구분되어야 한다.
- 람다는 간결하고 선언적인 코드를 선호할 때 적합하다.
- 익명 클래스는 상태 유지나 복수 메서드 구현이 필요한 경우 적합하다.
- 자바 8 이상에서는 람다가 실무에서 우선 고려되는 방식이며, 레거시와 복잡한 구현에는 익명 클래스도 여전히 유효하다.
'Dev Lang > Java' 카테고리의 다른 글
[Java] 함수형 인터페이스 완전 정복 – 제네릭, 타겟 타입, 내장 함수형 인터페이스까지 (0) | 2025.05.26 |
---|---|
[Java] 람다 완전 정리 – 함수형 프로그래밍의 시작 (1) | 2025.05.19 |
[Java] 자바 스레드에서 run()은 왜 체크 예외를 던질 수 없을까? (0) | 2025.05.12 |
[Java] ReentrantLock 공식문서 파헤쳐보기 (1) | 2025.04.23 |
[Java] 프록시 패턴을 통한 멀티 스레드 환경 조성하기 (0) | 2025.04.04 |