람다 vs 익명 클래스
#Java/adv3
- 문법 차이
- 익명 클래스
- 익명 클래스는 클래스를 선언하고 즉시 인스턴스를 생성하는 방식이다.
- 익명 클래스도 하나의 클래스이다.
- 람다 표현식
- 람다 표현식은 함수를 간결하게 표현할 수 있는 방식이다. ( 연산자 사용)
- 함수형 인터페이스(메서드가 하나인 인터페이스)를 간단히 구현할 때 주로 사용한다.
- 람다도 인스턴스가 생성된다.
- 익명 클래스
- 코드의 간결함
- 익명 클래스는 람다 표현식에 비해 코드의 양이 상대적으로 많다.
- 람다 표현식은 간결하고, 불필요한 코드를 최소화한다. 많은 생략 기능도 지원한다.
- 상속 관계
- 익명 클래스는 일반적인 클래스처럼 다양한 인터페이스와 클래스를 구현하거나 상속할 수 있다. 크게 제한사항이 없다.
- 람다 표현식은 메서드를 딱 하나만 가지는 함수형 인터페이스만을 구현할 수 있다. 클래스를 상속할 수 없다. 상태(필드, 멤버 변수)나 추가적인 메서드 오버라이딩은 불가능하다.
- 상태나 추가적인 상속이 필요하지 않은 상황에서만 사용할 수 있다.
- 호환성
- 람다 표현식은 자바 8 이전 버전에서 사용 불가능하다.
- this 키워드의 의미
- 익명 클래스 내부에서
this는 익명 클래스 자신을 가리킨다. 외부 클래스와 별도의 컨텍스트를 가진다. - 람다 표현식에서
this는 람다를 선언한 클래스의 인스턴스를 가리킨다(외부 클래스를 가리킨다). 즉, 람다 표현식은 별도의 컨텍스트를 가지는 것이 아니라, 람다를 선언한 클래스의 컨텍스트를 유지한다.
- 익명 클래스 내부에서
- 캡처링(capturing)
- 익명 클래스는 외부 변수에 접근할 수 있지만, 지역 변수는 반드시
final혹은 사실상final인 변수만 캡처할 수 있다. - 람다 표현식도 익명 클래스와 마찬가지로 캡처링을 지원한다. 마찬가지로
final혹은 사실상final인 변수만 캡처할 수 있다.
- 익명 클래스는 외부 변수에 접근할 수 있지만, 지역 변수는 반드시
- 생성 방식
- 익명 클래스는 새로운 클래스를 정의하고 객체 인스턴스를 생성하는 방식이다 컴파일 시 새로운 내부 클래스로 변환되어 클래스 파일이 생성된다.
- 람다는
invokeDynamic이라는 메커니즘을 사용하여 컴파일 타임에 실제 클래스 파일을 생성하지 않고, 런타임 시점에서 동적으로 필요한 코드를 처리한다.
원본 코드
public class FunctionMain {
public static void main(String[] args) {
Function<String, Integer> function = x -> x.length();
System.out.println("function1 = " + function.apply("hello"));
}
}
- 람다가 포함된 코드가 있다면 자바는 다음과 같이 컴파일 한다.
컴파일 코드
public class FunctionMain {
public static void main(String[] args) {
Function<String, Integer> function = 람다 인스턴스 생성(구현 코드는 lambda1() 연결);
System.out.println("function1 = " + function.apply("hello"));
}
// 람다를 private 메서드로 추가
private Integer lambda1(String x) {
return x.length();
}
}
- 컴파일 단계에서 람다를 별도의 클래스로 만드는 것이 아니라,
private메서드로 만들어 숨겨둔다.- 참고로 자바 내부에서 일어나는 일이므로 개발자가 이렇게 만들어진 코드를 확인하기는 어렵다.
- 그리고 실행 시점에 동적으로 람다 인스턴스를 생성하고, 해당 인스턴스의 구현 코드로 앞서 만든
lambda1()메서드가 호출되도록 연결한다. - 이론적으로는 람다가 메모리 성능에서 이점이 있지만, 차이는 미미하므로 사실상 실무에서 성능 차이는 없다고 봐도 된다.
- 상태 관리
- 익명 클래스는 인스턴스 내부에 상태(필드, 멤버 변수)를 가질 수 있다.
- 람다는 함수이기 때문에, 함수는 그 내부에 상태(필드)를 가지지 않고, 기능만 제공한다.
- 용도 구분
- 익명 클래스
- 상태 유지가 필요할 때
- 다중 메서드를 구현
- 복잡한 인터페이스 구현이 필요
- 기존 클래스 또는 인터페이스를 상속할 때
- 람다
- 상태 유지가 필요하지 않고, 간결함이 중요한 경우
- 단일 메서드만 필요한 간단한 함수형 인터페이스 구현 시
- 둘 다 선택할 수 있으면 대부분 람다를 선택하는게 더 나은 선택!
- 익명 클래스
'Java > Modern Java(8~)' 카테고리의 다른 글
| [Java] 63. 스트림 API1 - 기본 (0) | 2025.07.04 |
|---|---|
| [Java] 62. 메서드 참조 (0) | 2025.07.04 |
| [Java] 60. 람다 활용 (0) | 2025.07.04 |
| [Java] 59. 함수형 인터페이스 (0) | 2025.07.04 |
| [Java] 58. 람다 (0) | 2025.07.04 |