관리 메뉴

루시와 프로그래밍 이야기

ITEM43 람다보다는 메서드 참조를 사용하라 본문

스터디/이펙티브 자바

ITEM43 람다보다는 메서드 참조를 사용하라

Lucy_Ko 2022. 11. 18. 15:21

https://jjingho.tistory.com/92
람다는 익명 클래스보다 간결하다는 장점이 있다. 그런데 함수 객체를 람다보다 더 간결하게 만드는 방법이 있다. 바로 메서드 참조(Method Reference)다.

**https://countryxide.tistory.com/127

**https://developer-cheol.tistory.com/62

메서드 참조의 장점

메서드 참조는 람다의 거추장스러운 코드를 명확하고 간결하게 만들어준다.

다음 예제는 Map에 Key가 있다면 기존 매핑 값을 증가시키는 코드다.

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

 

count와 incr는 크게 하는 일 없이 공간을 차지한다. 이를 메서드 참조로 개선하면 똑같은 결과를 더 보기 좋게 표현할 수 있다.

//정적 메서드 참조
map.merge(key,1,Integer::sum);

 

메서드 참조를 사용하면 매개변수의 수가 늘어날수록 제거할 수 있는 코드가 많아진다.

 

메서드 참조를 사용할 때 주의사항

메서드 참조를 사용하면 대부분 코드가 간결해지고 명확해지지만, 그렇지 않은 경우도 있다. 람다에서 사용하는 매개변수 이름이 좋은 가이드가 된다면 코드의 길이가 더 길어도 메서드 참조보다 읽기 쉽고 유지보수도 쉬울 수 있다.

또한, 메서드 참조에 사용하는 메서드 이름이 길다면 오히려 람다가 더 간결하게 표현될 수 있다. 예를 들어 GoshThisClassNameIsHumongous라는 클래스에 action 메서드를 참조한다고 해보자.

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

 

너무 긴 이름 때문에 오히려 가독성이 떨어진다. 이를 람다로 표현하면 훨씬 간결해진다.

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

 

따라서 람다와 메서드 참조를 선택할 때, 메서드 참조가 짧고 명확한 표현을 할 수 있다면 메서드 참조를 사용하고, 그렇지 않을 때만 람다를 사용하면 된다.

 

메서드 참조의 유형

1. 정적 메서드 참조 (https://mygumi.tistory.com/253)

가장 흔한 메서드 참조 유형으로 정적 메서드를 참조한다. 앞서 살펴본 Integer::sum도 정적 메서드에 속한다.

// 메서드 참조
Integer::sum

// 람다
str -> Integer.pasrseint(str)

 

2. 한정적 인스턴스 메서드 참조

참조 대상 인스턴스를 특정하는 한정적 인스턴스 메서드 참조 유형이다. 근본적으로 정적 참조와 비슷하여 함수 객체가 받는 인수와 참조되는 메서드가 받은 인수가 똑같다.

// 메서드 참조
Instant.now()::isAfter

// 람다
Instant then = Instant.now();
t -> then.isAfter(t);

 

한정적 인스턴스 메서드 참조는 인스턴스의 함수 결과 값의 메서드를 참조한다.

한정적 참조는 정적 참조와 비슷하다. 즉, 함수 객체가 받는 인수와 참조되는 메서드가 받는 인수가 똑같다. 단지 인스턴스의 함수라는 차이일 뿐.

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=slrkanjsepdi&logNo=90130199296

3. 비한정적 인스턴스 메서드 참조

비한정적 인스턴스 참조는 함수 객체를 적용하는 시점에 수신 객체를 알려준다. 이를 위해 수신 객체 전달용 매개변수가 목록의 첫 번째로 추가되며, 그 후로 참조되는 메서드 선언에 정의된 매개변수들이 뒤따른다.

// 메서드 참조
String::toLowerCase

// 람다
str -> str.toLowerCase()

 

비한정적 인스턴스 메서드 참조는 주로 Stream 파이프라인에서의 매핑과 필터 함수에 쓰인다.

 

4. 클래스 생성자 참조

클래스의 생성자를 참조한다. 생성자 참조는 팩터리 객체로 사용된다.

// 메서드 참조
TreeMap<K,V>::new

// 람다
() -> new TreeMap<K, V>()

 

5. 배열 생성자 참조

배열 생성자를 참조한다.

// 메서드 참조
int[]::new

// 람다
len -> new int[len]
Comments