Home [Effective Java] Item43. 람다보다는 메서드 참조를 사용하라!
Post
Cancel

[Effective Java] Item43. 람다보다는 메서드 참조를 사용하라!

Item43. 람다보다는 메서드 참조를 사용하라!

  • 람다가 익명 클래스보나 나은 점은 간결함!
  • 그런데 자바엔 함수 객체를 람다보다 간결하게 만드는 방법이 있다?
    • 그것은 바로 메서드 참조다.

람다, 메서드 참조 비교

1
2
3
4
// lambda
map.merge(key, 1, (count, incr) -> count + incr);
// method reference
map.merge(key, 1, Integer::sum);
  • Map에 추가된 merge 메서드는 키, 값, 함수를 인수로 받는다.
    • 주어진 키가 아직 없다면, [키,값] 쌍을 그대로 저장한다.
    • 반대로 키가 이미 있다면, 함수를 현재 값과 주어진 값에 적용 후 그 결과를 덮어쓴다. [키, 함수(현재값, 주어진값)] 쌍 형태다.
  • 주어진 예제에서 람다는 두 인수의 합을 단순 반환할 뿐이다.
    • 이러한 경우 자바 8부터 제공되는 Integer 클래스의 정적 메서드인 sum을 이용하는 것이 간결함 유지에 더 도움이 된다.
  • 간결함을 위해 메서드 참조를 사용하는 것이 좋으나, 매개변수 이름 자체가 프로그래머에게 좋은 가이드가 될 수 있는 경우 람다를 사용한다.

  • 람다로 할 수 없는 일이라면 메서드 참조로도 할 수 없다.
    • 람다로 작성할 코드를 새로운 메서드에 담은 다음, 람다 대신 그 메서드를 참조해 사용하는 방식이기 때문이다.
  • 메서드 참조에는 기능을 잘 드러내는 이름을 지어줄 수 있다. 친절한 설명을 문서로 남길 수도 있다.

람다가 메서드 참조보다 간결한 경우

  • 주로 메서드와 람다가 같은 클래스에 있을 때 그렇다.

예시

1
2
3
4
// 메서드 레퍼런스를 사용하는 경우
service.execute(GoshThisClassNameIsHumongous::action);
// 람다를 사용하는 경우
service.execute(() -> action());
  • 코드가 GoshThisClassNameIsHumongous 클래스 안에 있는 경우
    • 메서드 참조라고 해서 더 짧기도, 더 명확하지도 않다.
    • 이러한 경우엔 람다를 사용하는 것이 더 좋다.

메서드 참조의 다섯 가지 유형

  • 가장 흔한 유형은 앞의 예에서 본 것처럼 정적 메서드를 가리키는 메서드 참조다.
  • 인스턴스를 참조하는 유형이 두 가지 있다.
    • 수신 객체(참조 대상 인스턴스)를 특정하는 한정적(bound) 인스턴스 메서드 참조
      • 함수가 받은 인수와 참조되는 메서드가 받는 인수가 같다.
    • 수신 객체를 특정하지 않는 비한정적(unbound) 인스턴스 메서드 참조
      • 함수 객체를 적용하는 시점에 수신 객체를 알려준다.
      • 이를 위해 수신 객체 전달용 매개변수가 매개변수 첫 목록이 되고, 참조되는 선언에 사용되는 매개변수가 이를 뒤따른다.
  • 생성자 참조가 있다. 생성자 참조는 팩터리 객체로 사용된다.
    • 클래스 생성자를 가리키는 메서드 참조
    • 배열 생성자를 가리키는 메서드 참조
메서드 참조 유형같은 기능을 하는 람다
정적Integer::parseIntstr -> Integer.parseInt(str)
한정적 (인스턴스 참조)Instant.now()::isAfterInstant then = Instant.now();
t -> then.isAfter(t)
비한정적 (인스턴스 참조)String::toLowerCasestr -> str.toLowerCase()
클래스 생성자TreeMap<K, V>::new() -> new TreeMap<K,V>()
배열 생성자int[]::newlen -> new int[len]

핵심 정리

  • 메서드 참조는 람다의 간단명료한 대안이 될 수 있다.
  • 우선 메서드 참조 쪽을 고려한다.
    • 람다와 비교했을 때, 람다로 표현한 것이 더 짧고 명확하다면 람다를 사용한다.
This post is licensed under younghwani by the author.

[Effective Java] Item42. 익명 클래스보다는 람다를 사용하라!

[Effective Java] Item44. 표준 함수형 인터페이스를 사용하라!

Comments powered by Disqus.