ITEM 43 "람다보다는 메서드 참조를 사용하라"
람다보다도 더 간결하게 작성할 수 있는 방법이 있다. 바로 메서드 참조이다.
map.merge(key, 1, (count, incr) -> count + incr);
위 코드는 자바 8 때, Map 에 추가된 merge 메서드이다. 키, 값, 함수를 인수로 받으며 주어진 키가 맵에 없다면 주어진 [키, 값] 쌍을 그대로 저장하고, 반대로 키가 있으면 [키, 함수의 결과] 쌍을 저장한다. 깔끔해 보이지만, count 와 incr 가 크게 하는 일 없이 공간만 차지한다. 자바 8이 되면서 Integer 클래스는 이 람다와 같은 기능을 가진 정적 메서드 sum 을 제공했다.
map.merge(key, 1, Integer::sum);
더 간결해진 것을 볼 수 있다. 하지만 메서드 참조는 함수의 이름만 명시하기 때문에 단번에 이해가 되지 않을 수도 있다.
매개변수의 이름 자체가 프로그래머에게 힌트를 준다면 람다가 더 좋은 선택지가 될 수도 있다. (매개변수가 여러 개이고 함수 이름으로 단 번에 파악이 안 된다면)
단 번에 파악할 목적이 아니고 해당 함수의 선언 부분으로 이동하는 수고로움을 감수할 수 있다면, 똑같은 인자 구성으로 함수를 만든 다음, 메서드 참조를 사용하는 것이 더 좋다. 메서드 참조에는 기능을 잘 드러내는 이름을 지어줄 수 있고, 친절한 설명을 문서에도 남길 수 있으니 말이다. 하지만 같은 클래스 안에 있는 기능을 호출하는 것이라면 람다가 더 간결하다.
// 1 번째 방법
service.execute(GoshThisClassNameIsHumongous::action);
// 2 번째 방법
service.execute(() -> action());
메서드 참조에는 아래와 같이 5가지 유형이 있다.
메서드 참조 유형 | 예 | 같은 기능을 하는 람다 |
정적 | 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] |
"메서드 참조 쪽이 짧고 명확하다면 메서드 참조를 사용하고, 그렇지 않을 때만 람다를 사용한다"
'독후감 > Effective JAVA' 카테고리의 다른 글
[Effective JAVA] 44 "표준 함수형 인터페이스를 사용하라" (0) | 2024.03.03 |
---|---|
[Effective JAVA] 42 "익명 클래스보다는 람다를 사용하라" (1) | 2024.03.02 |
[Effective JAVA] 41 "정의하려는 것이 타입이라면 마커 인터페이스를 사용하라" (0) | 2023.11.06 |
[Effective JAVA] 40 "@Override 애너테이션을 일관되게 사용하라" (1) | 2023.10.29 |
[Effective JAVA] 39 "명명 패턴보다 애너테이션을 사용하라" (1) | 2023.10.24 |