이번장의 핵심은...
메서드 참조는 람다의 간단명료한 대안이 될 수 있다
메서드 참조 쪽이 짧고 명확하다면 메서드 참조를 쓰고, 그렇지 않을 때만 람다를 사용하라
메서드 참조
함수 객체를 람다보다 더 간결하게 만드는 방법입니다
메서드 참조를 사용하는 편이 보통은 더 짧고 간결하므로, 람다로 구현했을 때 너무 길거나 복잡하다면 메서드 참조가 좋은 대안입니다
기능을 잘 드러내는 이름을 짓거나 친절한 설명을 문서로 남길 수도 있습니다
IDE들은 람다를 메서드 참조로 대체하라고 권하고 있습니다
보통은 이득이지만 항상은 아닙니다
때로는 람다가 더 간결할 수 있습니다
// 메서드 참조
service.execute(GoshThisClassNameIsHumongous::action);
// lamda
service.execute(()->action());
메서드 참조가 더 짧지도, 더 명확하지도 않습니다
람다 쪽이 더 낫습니다
자바 8때 Map에 추가된 merge 메서드
map.merge(key, 1, (count,incr) -> count+incr);
키, 값, 함수를 인수로 받습니다
map에 키가 없다면 주어진 {키:값} 쌍을 그대로 저장합니다
map에 키가 존재하면 함수를 현재 값과 주어진 값에 적용합니다 (그리고 그 결과로 값을 덮어씁니다) - {키:함수의결과}
깔끔해보이지만 매개변수 count와 incr은 크게 하는 일 없이 공간만 차지하고 있습니다
그냥 이 람다는 두 인수의 합을 단순히 반환해줍니다
자바 8부터 Integer 클래스(와 모든 기본의 박싱 타입)은 이 람다와 기능이 같은 정적 메서드 sum을 제공합니다
map.merge(key, 1, Integer::sum)
따라서 람다 대신 이 메서드의 참조를 전달하면 똑같은 결과를 더 보기 좋게 얻을 수 있습니다
매개변수 수가 늘어날 수록 메서드 참조로 제거할 수 있는 코드양도 늘어납니다
(하지만 때론 람다를 사용할 때 매개변수 이름 자체가 좋은 가이드가 될 수 있습니다
이런 람다는 길이는 더 길지만 메소드 참조보다 더 읽기 쉽고 유지보수도 쉬울 수 있습니다)
람다로 할 수 없는 일이라면 메서드 참조로도 할 수 없다
예외) 제네릭 함수 타입
람다로는 불가능하나 메서드 참조로는 가능한 유일한 예외입니다
함수형 인터페이스의 추상 메서드가 제네릭일 수 있듯이 함수 타입도 제네릭일 수 있습니다
interface G1 {
<E extends Exception> Object m() throws E;
}
interface G2 {
<F extends Exception> String m() throws Exception;
}
interface G extends G1, G2 {
}
// 함수형 인터페이스 G를 함수 타입으로 표현하면
<F extends Exception> () -> String throws F
함수형 인터페이스를 위한 제네릭 함수 타입은 메서드 참조 표현식으로 구현할 수 있지만,
람다식으로는 불가능합니다 (제네릭 람다식이라는 문법이 존재하지 않습니다)
이 글은 “이펙티브 자바 3판” 책 내용을 정리한 글입니다.
만약 저작권 관련 문제가 있다면 “shk3029@kakao.com”로 메일을 보내주시면, 바로 삭제하도록 하겠습니다.
'Java > Effective Java 3E' 카테고리의 다른 글
[이펙티브자바 3판] ITEM45. 스트림은 주의해서 사용하라 (0) | 2020.12.02 |
---|---|
[이펙티브자바 3판] ITEM44. 표준 함수형 인터페이스를 사용하라 (0) | 2020.12.02 |
[이펙티브자바 3판] ITEM42. 익명 클래스보다는 람다를 사용하라 (0) | 2020.12.01 |
[이펙티브자바 3판] ITEM41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2020.11.29 |
[이펙티브자바 3판] ITEM40. @Override 애너테이션을 일관되게 사용하라 (0) | 2020.11.29 |
댓글