전공공부
[아이템 42] 익명 클래스 보다는 람다식을 사용하라 본문
함수 객체를 표현하는 방식에는 익명 클래스를 이용하여 함수 객체를 표현하여 사용하였다.
하지만, 익명 클래스의 인스턴스를 함수 객체로 사용하는 것은 낡은 기법이며 코드를 길어지게 한다.
Collection.sort(words, new Comparator<String>() {
public int compare(String s1, String s2){
return Integer.compare(s1.length(), s2.length());
}
});
기존의 익명 클래스를 활용하여 문자열의 길이를 기준으로 오름차순 정렬을 시도하였다.
해당 코드는 자바8에서는 간결히 표현 할 수 있다.
추상 메서드 하나짜리 인터페이스는 특별한 의미를 인정 받아서 특별한 대우를 받게 되었다.
아래와 같은 람다식으로 말이다.
Collection.sort(words, (s1,s2) -> Integer.compare(s1.length(), s2.length()));
위와 같이 간결하게 표현이 가능하다.
위 예제는 아이템26의 제네릭은 로 타입의 사용을 자제하라와 아이템 29의 제네릭을 사용하라와 아이템 30의 제네릭 메서드를 사용하라와도 겹치는 예제이다. 로 타입을 사용하게 되면 컴파일러는 제네릭으로 부터 타입 추론을 하는데 이 때, 타입 추론이 불가능하여 타입 에러가 났을 것이고 예제 코드는 제네릭의 메서드를 활용하였기 때문이다.
제네릭 타입인 T를 가지고 추론을 할 수 있다.
열거 타입 - 람다식의 활용
public enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
public abstract double apply(double x, double y);
}
기존의 열거 타입의 활용은 상수별 클래스 몸체를 사용해서 각 상수에서 apply를 구현함
public enum Operation {
PLUS("+", (x, y) -> x + y), //열거타입 내부 생성자에서는 컴파일 타임에서 타입이 추론됌
MINUS("-", (x, y) -> x - y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
람다식을 활용하면 열거 타입의 인스턴스 필드를 이용하여서 상수별로 다르게 작동하는 코드를 만들 수 있음
그래서, 람다식은 언제나 쓰는 것이 좋을까?
답은, 아니다이다.
람다는 보다 싶이 이름이 없고 문서화를 할 수 없다. 따라서 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야 한다.
그리고, 위 예제에서 열거 타입 생성자에 넘겨지는 인수들의 타입도 컴파일타임에 추론된다. 따라서 열거 타입 생성자 안의 람다는 열거타입의 인스턴스 멤버에 접근할 수 없다. (인스턴스는 런타임에 만들어짐)
그래서, 인스턴스 필드나 메서드에 접근을 해야 하면 상수별 클래스 몸체를 구현해야 한다.
추가 정보
- 람다에서 this 키워드는 바깥 인스턴스를 가르키며 이와 반대로 익명 클래스의 this는 내부 인스턴스를 가르킨다.
- 람다도 익명클래스 처럼 직렬화 형태가 달라서 람다를 직렬화하는 일은 극히 삼가야 한다.
'Study > Java' 카테고리의 다른 글
[아이템 54] null이 아닌, 빈 컬렉션이나 배열을 반환하라 (0) | 2023.06.20 |
---|---|
[아이템 47] 반환 타입으로는 스트림보다 컬렉션이 낫다. (0) | 2023.05.06 |
[아이템 38] 확장 할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 (0) | 2023.04.25 |
[아이템 31] 한정적 와일드카드를 사용해 API 유연성을 높이라 (0) | 2023.04.04 |
아이템 19. 상속을 고려해 설계하고 문서화하라. 그러지 않았다면 상속을 금지하라 (0) | 2023.03.05 |