개발/Java

메서드 참조

Debin 2022. 3. 9.
반응형

메서드 참조

이제 람다 표현식에 이어 메서드 참조에 대해 알아보자.

메서드 참조를 이용해 기존의 메서드 정의를 재활용해서 람다처럼 전달할 수 있다.

때로는 람다 표현식보다 메서드 참조를 사용하는 것이 더 가독성이 좋으며 자연스러울 수 있다.

 

다음은 메서드 참조와 새로운 자바8 API를 이용한 정렬 예시다.

//기존 코드
inventory.sort((Apple a1, Apple a2) -> a1.getWeight().compareTo(a2.getWeight())));

//다음은 메서드 참조와 java.util.Comparator.comparing을 활용한 코드다.
inventory.sort(comparing(Apple::getWeight)); //이제부터 이 문법에 대해 알아보자.

 

메서드 참조는 특정 메서드만을 호출하는 람다의 축약형이라고 생각할 수 있다.

예를 들어 람다가 '이 메서들르 직접 호출해'라고 명령한다면 메서드를 어떻게 호출해야 하는지 설명을 참조하기보다는

메서드명을 직접 참조하는 것이 편리하다.

 

실제로 메서드 참조를 이용하면 기존 메서드 구현으로 람다 표현식을 만들 수 있다.

 

이때 명시적으로 메서드명을 참조함으로써 가독성을 높일 수 있다.

메서드명 앞에 구분자(::)를 붙이는 방식으로 메서드 참조를 활용할 수 있다. 

 

이제 아래 예시들을 살펴보자.

람다 메서드 참조 단축 표현
(Apple apple) -> apple.getWeight() Apple::getWeight
() -> Thread.currentThread().dumpStack() Thread.currentThread::dumpStack
(str, i) -> str.substring(i) String::substring
(String s) -> System.out.println(s) System.out::println
(String s) -> this.isValidName(s) this::isValidName

메서드 참조를 새로운 기능이 아니라 하나의 메서드를 참조하는 람다를 편리하게 표현할 수 있는 문법으로 간주할 수 있다.

메서드 참조를 이용하면 같은 기능을 더 간결하게 구현할 수 있다.

메서드 참조를 만드는 방법

메서드 참조는 세 가지 유형으로 구분할 수 있다.

 

  1. 정적 메소드 참조
    예를 들어 Integer의 parseInt 메서드는 Integer::parseInt로 표현할 수 있다.
  2. 다양한 형식의 인스턴스 메서드 참조
    예를 들어 String의 length 메서드는 String::length로 표현할 수 있다.
  3. 기존 객체의 인스턴스 메서드 참조
    예를 들어 Transaction 객체를 할당받은 expensiveTransaction 지역 변수가 있고,
    Transaction 객체에는 getValue 메서드가 있다면, 이를 expensiveTransaction::getValue라고 표현할 수 있다.

세 번째 유형의 방식이 유독 이해가 가지 않았다.

이 유형의 메서드 참조는 람다 표현식에서 현존하는 외부 객체의 메서드를 호출할 때 사용된다.

예를 들어 expensiveTransaction.getValue()라는 람다 표현식을 expensiveTransaction::getValue로 줄여서 표현할 수 있다.

세 가지 종류의 람다 표현식을 메서드 참조로 바꾸는 방법

컴파일러는 람다 표현식의 형식을 검사하던 방식과 비슷한 과정으로 메서드 참조가 주어진 함수형 인터페이스와 호환하는지 확인한다.

즉, 메서드 참조는 콘텍스트의 형식과 일치해야 한다.

 

참고 문헌

모던 자바 인 액션 (라울-게이브리얼 우르마) - 3장 람다 표현식

반응형

댓글