Intro::
이펙티브 자바 정리본입니다.
결론
•
익명 클래스는 함수형 인터페이스가 아닌 타입의 인스턴스를 만들 때만 사용해야 합니다.
•
람다는 이름이 없고 문서화도 못하기 때문에 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 사용하지 말하야 합니다.
◦
람다식은 3줄이 넘어가면 가독성이 급격하게 나빠집니다.
•
람다를 직렬화하는 일은 극히 삼가해야 합니다.
왜 람다를 사용해야 하는가
•
기존의 익명 클래스 방식은 코드가 너무 길기 때문에 함수형 프로그래밍에 적합하지 않습니다.
•
컴파일러가 문맥을 살펴 타입을 추론해주기 때문에 코드가 간결해 집니다.
// 익명함수 예시
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; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
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);
}
Java
복사
// 람다식 예시
public enum Operation {
PLUS ("+", (x, y) -> x + y),
MINUS ("-", (x, y) -> x - y),
TIMES ("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
@Override public String toString() { return symbol; }
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
Java
복사
람다로 대체 불가능한 곳
•
람다는 함수형 인터페이스에서만 사용합니다. 예컨데 추상 클래스의 인스턴스를 만들 때 람다를 쓸 수 없으니, 익명 클래스를 사용해야 합니다.
•
비슷하게 추상 메서드가 여러 개인 인터페이스의 인스턴스를 만들 때도 익명 클래스를 쓸 수 있습니다.
•
람다는 자신을 참조할 수 없기 때문에 함수 객체가 자신을 참조해야 한다면 익명 클래스를 사용해야 합니다.
질문
추상 클래스의 인스턴스를 만들 때 람다를 쓸 수 없다고 하는데 이해가 안간다
•
람다 표현식은 오직 하나의 추상 메서드만을 가진 인터페이스에서 그 추상 메서드를 구현할 때만 사용 가능합니다.
◦
예: Runnable, Callable, ActionListener와 같은 함수형 인터페이스.
•
추상 클래스는 여러 개의 메서드를 가질 수 있고, 일부 메서드는 이미 구현되어 있을 수도 있으며, 모든 추상 메서드가 구현되어야만 인스턴스를 생성할 수 있습니다.
◦
이 때문에 추상 클래스는 람다 표현식으로 인스턴스를 만들 수 없습니다.
인터페이스에서도 메서드가 하나보다 많다면 추상클래스와 마찬가지로 람다를 사용해 인스턴스를 만들 수 없습니다. 즉, 람다란 단 하나의 추상 메서드를 가지는 인터페이스(함수형 인터페이스)에서 그 단일 메서드를 간단하게 구현하기 위한 방법입니다.
References::
이펙티브 자바 / 조슈아 블로크 지음 (프로그래밍 인사이트)