- 람다가 익명 클래스보다 나은 점 - 간결함
- 자바에서는 함수 객체를 람다보다 더 간결하게 만드는 방법이 존재 - 메서드 참조
메서드 참조
아래는 임의의 키와 Integer 값의 매핑을 관리하는 프로그램의 일부 코드이다.
이 때 값이, 키의 인스턴스 개수로 해석될 때 해당 프로그램은 multiset을 구현한게 되는데, 키가 맵안에 없다면 key를 1로 매핑하고 이미 있다면 기존 매핑 값을 증가시키는 코드이다.
map.merge(key, 1, (count, incr)->count+incr);
- 해당 코드에서는 각 변수의 이름이 중요하지 않고, 더불어 코드 공간을 차지하게 된다.
이 때 count와 incr의 타입이 Integer일 때 다음과 같은 코드로 간결하게 할 수 있다.
map.merge(key, 1, Integer::sum);
- 람다로 표현할 수 없다면, 마찬가지로 메서드 참조로도 표현(구현)할 수 없다는 것을 유의하자
- ctex) 제네릭 함수 타입 - 제네릭 람다식이란 문법이 존재하지 않기 때문에 메서드 참조 표현식으로만 가능
- 람다로 구현했을 때도, 표현식이 길거나 복잡하다면 메서드 참조가 좋은 대안이 될 수 있다.
- 메서드 참조를 통해 네이밍이 가능해지고, 이를 통해 문서화가 가능하다.
private static final Human human;
IntStream.range(1, 5)
.flatmap(i -> {
i += 5;
human.setAge(i);
return Mono.just(human);
})
.flatmap(...)
============================================================
IntStream.range(1, 5)
.flatmap(this::convertHuman)
.flatmap(...)
private Mono<Human> convertHuman(Integer num) {
num += 5;
human.setAge(num);
return Mono.just(human);
}
# 늘 메서드 참조가 정답이 아닌 이유
- 람다의 매개변수 자체가 코드 이해에 도움이 되는 경우도 있다.
- 메서드 참조는 코드를 간결하게 해주지만, 코드의 의미까지 간결하게 하는 부작용을 초래할 수 있다.
- 메서드 참조가 더 길 때도 존재한다.
service.execute(GoshThisClassNameIsHumongous::action);
service.execute(() -> action());
# 메서드 참조 유형의 종류
1. 정적 메서드 참조
// 정적 (둘은 같은 역할을 한다.)
Integer::parseInt; // 메서드 참조
str -> Integer.parseIng(str); // 람다
2. 한정적(bound) 인스턴스 메서드 참조 - 수신 객체를 특정할 때
// 한정적 (인스턴스)
Instant.now()::isAfter;
Instant then = Instant.now();
t -> then.isAfter(t);
3. 비한정적(unbound) 인스턴스 메서드 참조 - 수신 객체가 특정되지 않을 때
// 비한정적 (인스턴스)
String::toLowerCase;
str -> str.toLowerCase();
4. 클래스 생성자
// 클래스 생성자
TreeMap<K,V>::new;
() -> new TreeMap<K,V>();
5. 배열 생성자
// 배열 생성자
int[]::new;
len -> new int[len];
정리 :
메서드 참조는 람다보다 더욱 간결하고 명시적인 대안이 될 수 있다.
따라서 개발자는 메서드 참조 쪽이 짧고 명확하다면 메서드 참조를 사용하고 그렇지 않을 때만 람다를 사용하라
'Effective Java' 카테고리의 다른 글
[Effective Java] 아이템 45 - 스트림은 주의해서 사용하라 (0) | 2022.03.25 |
---|---|
[Effective Java] 아이템 44 - 표준 함수형 인터페이스를 사용하라 (0) | 2022.03.25 |
[Effective Java] 아이템 42 - 익명 클래스보다는 람다를 사용하라 (0) | 2022.03.23 |
[Effective Java] 아이템 41 - 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2022.03.23 |
[Effective Java] 아이템 40 - @Override 애너테이션을 일관되게 사용하라 (0) | 2022.03.23 |