지난 번 글에서 Java 8 에서 등장한 람다 표현식에 대해 정리했다.

오늘은 두번재로 메서드 참조에 대해 알아보자.

버전
기능 종류 설명
8 Lambda Expression 및
Method Reference 도입
Language anonymous inner class 표현 간략화 (함수형 표현)
인자로 method reference를 전달 (함수형 표현)
8 Collections & Streams Language Collections에서 Streams API를 사용하여, 이전의 반복문이 아닌 함수형 구현
8 Interface Default Method 도입 Language interface 내부에서 default 메서드를 선언할 수 있다.
8 Optional Class 도입 Language Optional Class를 이용하여 NullPointerException이 발생하는 것을 방지해 준다.

메서드 레퍼런스의 정의

메소드 레퍼런스(method reference)는 기존의 메서드를 정의를 활용해서 람다처럼 전달할 수 있다.

때로는 람다표현식보다 메서드 레퍼런스를 이용하는 것이 더 가독성이 좋고 자연스러울 때가 있다.

아래의 예를 보면 확실히 알 수 있다.

어떤 기능을 하는 메서드인지 확실히 눈에 들어온다.

// 기존 람다식으로 표현한 메서드
inventory.sort((Apple a, Apple b) ->
				a.getWeight().compareTo(b.getWeight());
                
// 메서드 레퍼런스를 활용한 코드
inventory.sort(comparing(Apple::getWeight));

 

그렇다면, 메서드 레퍼런스가 왜 중요할까?

메서드 레퍼런스는 특정 메서드만을 호출하는 람다의 축약형이라고 볼 수 있다.

람다가 이 메서드를 호출해라고 했을 때 메서드를 어떻게 호출하는지 표현하는 것보다 메서드 명을 참조하는 것이 나을 때가 있다.

실제로 메서드 레퍼런스는 기존 메서드 구현으로 람다 표현식을 만들 수 있다.

이때 명시적으로 메서드명을 참조하게 되고 가독성을 높일 수 있다.

결과적으로 위의 Apple::getWeight은 (Apple a) -> a.getWeight() 를 축약한 것과 같다.

 

 

 

 

메서드 레퍼런스 문법

메소드 참조를 사용하면 불필요한 매개변수를 제거하고 다음과 같이 '::' 기호를 사용하여 표현할 수 있다.

클래스 이름으로 바로 메소드를 호출하거나, 참조 변수 이름으로 메소드를 호출하는 방식이다.

실제 메서드를 호출하는 것은 아니기 때문에 괄호가 없다는 것을 기억하자.

클래스이름::메소드이름
or 
참조변수이름::메소드이름

다양하게 사용되는 람다와 메서드 레퍼런스 단축 예제

람다 메서드 레퍼런스
(Apple a) -> a.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

 

메서드 레퍼런스 종류

 

static 메서드 레퍼런스

ex) Integer의 parseInt 메서드는 Integer::parseInt로도 표현 가능하다.

 

인스턴스 메서드 레퍼런스

ex) String 의 length 메서드는 String::length 로 표현 가능하다.

 

참조 변수 메서드 레퍼런스

ex) Transaction 객체를 할당받은 expensiveTransaction 지역변수가 있고, Transaction 객체에는 getValue 메서드가 있다면

이를 expensiveTransaction::getValue 라고도 표현할 수 있다.

 

+ Recent posts