람다는 익명 클래스보다 간결하다는 특징이 있다.
그런데 자바에는 람다보다 함수 객체를 더 간결하게 만드는 방법이 있는데, 그게 바로메서드 참조(method reference)
다.
multiset을 구현하는 예제를 통해 람다와 메서드 참조를 비교해보자.
람다 이용
map.merge(key, 1, (count, incr) -> count + incr);
메서드 참조 이용
모든 기본 타입의 박싱 타입은 정적 메서드 sum
을 제공하기 때문에 이 메서드의 참조를 전달하면 다음과 같이 작성할 수 있다.
map.merge(key, 1, Integer::sum);
장점
메서드 참조가 보통은 람다보다 더 짧고 간결하다.
그렇기 때문에 람다로 구현했을 때 너무 길거나 복잡하다면 메서드 참조가 좋은 대안이 되어준다.
즉, 람다로 작성할 코드를 새로운 메서드에 담은 다음, 람다 대신 그 메서드 참조를 사용하는 식이다.
메서드 참조에는 기능을 잘 드러내는 이름
을 지어줄 수 있고 친절한 설명을 문서
로 남길 수도 있다.
그러나 람다가 길이는 더 길지만, 메서드 참조보다 읽기 쉽고 유지보수도 쉬울 수 있다.
또 때론 람다가 메서드 참조보다 간결할 때도 있다. 주로 메서드와 람다가 같은 클래스에 있을 때 그렇다.
GoshThisClassNameIsHumongous 클래스 안에 다음 코드가 있다고 해보자.
메서드 참조 이용
service.execute(GoshThisClassNameIsHumongous::action);
람다 이용
service.execute(() -> action);
이때는 람다가 더 명확하고 간결하다.
메서드 참조의 유형은 5가지가 있다.
앞서 봤던 예제에서 사용했던, 가장 흔한 유형이다.
수신 객체(receiving object; 참조 대상 인스턴스)를 특정하는 메서드 참조다.
근본적으로 정적 메서드 참조와 비슷하다.
함수 객체가 받는 인수와 참조되는 메서드가 받는 인수가 똑같다.
수신 객체를 특정하지 않는 메서드 참조다.
함수 객체를 적용하는 시점에 수신 객체를 알려준다.
이를 위해 수신 객체 전달용 매개변수가 매개변수 목록의 첫 번째로 추가되고, 그 뒤에 참조되는 메서드 선언에 정의된 매개변수들이 뒤따른다.
주로 스트림 파이프라인에서의 매핑과 필터 함수에 쓰인다.
생성자 참조는 팩터리 객체로 사용된다.
📌 핵심 정리
메서드 참조는 람다의 간단명료한 대안이 될 수 있다.
메서드 참조 쪽이 짧고 명확하다면 메서드 참조를 쓰고, 그렇지 않을 때만 람다를 사용하라.