Intro::
이펙티브 자바 정리본입니다.
결론
•
메서드 참조 쪽이 람다보다 짧고 명확하다면 메서드 참조를 쓰고, 그렇지 않다면 람다를 사용하면 됩니다.
람다 vs 메서드 참조
// 람다 예시
map.merge(key, 1, (count, incr) -> count + incr0;
// 메서드 참조 예시
map.merge(key, 1, Integer::sum)
Java
복사
매개변수 수가 늘어날수록 메서드 참조로 제거할 수 있는 코드양도 늘어납니다.
람다가 할 수 없는 일이라면 메서드 참조로도 할 수 없습니다. 그렇더라도 메서드 참조를 사용하는 편이 보통은 더 짧고 간결하므로, 람다로 구현했을 때 너무 길거나 복잡하다면 메서드 참조가 좋은 대안이 될 수 있습니다.
일반적으로 IDE의 권고를 따라 람다를 메서드 참조로 대체하는 것이 이득이지만, 아닌 경우도 존재한다.
// 메서드 참조 예시
service.excute(DoshThisClassNameIsHumongous::action)
// 람다 예시
service.excute(() -> action());
Java
복사
위의 예시에서 확인해보면 메서드 참조가 명확하지도, 짧지도 않기 때문에 람다를 사용하는 편이 오히려 낫은 경우입니다.
메서드 참조의 유형
메서드 참조 유형 | 예 | 같은 기능을 하는 람다 |
정적 | Integer::parseInt | str → Integer.parseInt(str) |
한정적(인스턴스) | Instant.now()::isAfter | Instant then = Instant.now();
t → then.isAfter(t) |
비한정적(인스턴스) | String::toLowerCase | str → str.toLowerCase() |
클래스 생성자 | TreeMap<K, V>::new | () → new TreeMap<K, V>() |
배열 생성자 | int[]::new | len → new int[len] |
질문
함수형 인터페이스를 위한 제네릭 함수 타입은 메서드 참조 표현식으로는 구현할 수 있지만, 람다식으로 불가능하다는 말이 이해가 안간다.
interface G1 {
<E extends Exception> Object m() throws E;
}
interface G2 {
<F extends Exception> String m() throws Exception;
}
interface G extends G1, G2 {}
<F extends Exception> ()->String throws F
Java
복사
References::
이펙티브 자바 / 조슈아 블로크 지음 (프로그래밍 인사이트)