본문 바로가기
Effective Java

[Effective Java] 아이템43 람다보다는 메서드 참조를 사용하라

by byeongoo 2021. 6. 21.

■ 메서드 참조

자바에는 함수 객체를 람다보다도 더 간결하게 만드는 방법이 있다. 바로 메서드 참조이다.

 

아래 코드는 람다를 사용하고 있는 코드이다. merge는 자바 8 때 Map 추가된 merge 메서드를 사용하여, 키값이 있을 경우 함수를 현재 값과 주어진 값에 적용하고, 키 값이 없을 경우 주어진 키와 값을 그대로 저장한다. 

map.merge(key, 1, (count, incr) -> count+incr);

 

깔끔해 보이지만 매개변수인 count와 incr은 크게 하는 일 없이 공간을 차지한다. 사실 이 람다는 두 인수의 합을 단순히 반환할 뿐이다. 자바 8이 되면서 Integer 클래스(와 모든 기본 타입의 박싱 타입)는 이 람다와 기능이 같은 정적 메서드 sum을 제공한다. 이 메서드 참조를 이용하면 더 간결하게 코드를 만들 수 있다.

map.merge(2, 1, Integer::sum);

 

■ 람다를 사용하는게 나을 경우

너무 긴 메서드 이름은 오히려 람다가 더 가독성이 뛰어나다.

//메서드 참조 사용
service.execute(GoshThisClassNameIsHumongous::action);

//람다 사용
service.execute( () -> action() );

 

다른 예시 코드로는 java.util.function 패키지가 제공하는 제네릭 정적 팩터리 메서드인 Function.identity()를 사용하기보다는 똑같은 기능의 람다 (x->x)를 직접 사용하는 편이 코드도 짧고 명확하다.

 

또한 어떤 람다에서는 매개변수의 이름 자체가 프로그래머에게 좋은 가이드가 되기도한다.

 

■ 한정적 참조

인스턴스 메서드를 참조하는 유형이 두 가지가 있는데 그중 하나는 참조 대상 인스턴스를 특정하는 한정적인스턴스 메서드 참조이다. 다른 하나는 수신 객체를 특정하지 않는 비한정적 인스턴스 메서드 참조이다.

 

즉, 한정적 메서드 참조는 인스턴스에 함수의 결과값의 메서드를 참조하는 것이다.

LocalDate targetDate = LocalDate.now();
Predicate<LocalDate> localDateUnaryOperator = targetDate.minusDays(1)::isAfter;

 

■ 메서드 참조 유형

■ 람다로는 불가능하나 메서드 참조로 가능한 유일한 예

람다로는 제네릭 함수타입 구현을 표현할 수 없다. 메서드 참조로만 가능하다.

 

 정리

메서드 참조는 람다의 간단명료한 대안이 될 수 있다. 메서드 참조 쪽이 짧고 명확하다면 메서드 참조를 쓰고, 그렇지 않을 때만 람다를 사용하라.