티스토리 뷰
자바 8에는 다양한 기술들을 살펴보려고 하는데, 그 세 번째는 메서드 레퍼런스이다.
람다가 하는 일이 기존 메서드 또는 생성자를 호출하는 거라면, 메서드 레퍼런스를 사용해서 매우 간결하게 표현할 수 있다.
메서드 레퍼런스 실습을 위해 간단한 클래스를 작성하였다.
public class Greeting {
private String name;
public Greeting() {
}
public Greeting(String name) {
this.name = name;
}
public String hello(String name) {
return "hello " + name;
}
public static String hi(String name) {
return "hi " + name;
}
public String hello() {
return "hello " + this.name;
}
}
위 클래스에는 생성자와 인스턴스 메서드, 스태틱 메서드가 존재한다.
이제 위 Greeting이라는 클래스를 사용해보는 예제 코드를 살펴보자.
스태틱 메서드 참조
Greeting 클래스의 스태틱 메서드인 hi를 사용해보자.
람다 표현식을 사용한 코드와 비교해서 살펴보자.
import java.util.function.*;
public class App {
public static void main(String[] args) {
// 람다 표현식
UnaryOperator<String> hiByLambda = (str) -> "hi " + str;
UnaryOperator<String> hiByMethodReference = Greeting::hi;
System.out.println(hiByMethodReference.apply("eric"));
}
}
특정 객체의 인스턴스 메서드 참조
import java.util.function.*;
public class App {
public static void main(String[] args) {
Greeting greeting = new Greeting();
UnaryOperator<String> hiByMethodReference = greeting::hello;
System.out.println(hiByMethodReference.apply("eric"));
}
}
생성자 참조
import java.util.function.*;
public class App {
public static void main(String[] args) {
// 빈 생성자
Supplier<Greeting> supplier = Greeting::new;
System.out.println(supplier.get().hi("eric"));
// name을 받는 생성자
Function<String, Greeting> ericGreeting = Greeting::new;
System.out.println(ericGreeting.apply("eric").hello());
}
}
위 생성자 참조는 getter를 통해서 파악할 수 있다.
그 전에는 파악하기 어려움.
임의 객체의 인스턴스 메서드 참조
먼저, Comparator를 익명 클래스로 구현한 코드이다.
import java.util.Arrays;
import java.util.Comparator;
public class App {
public static void main(String[] args) {
String[] names = {"eric", "kwon", "keesun"};
Arrays.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return 0;
}
});
}
}
자바 8부터는 Comparator 인터페이스에 스태틱 메서드와 default 메서드가 추가되었다.
참고로, Comparator는 함수형 인터페이스이다.
⇒ Comparator를 들어가보면 FunctionalInterface 애너테이션이 붙어있음.
즉, Comparator는 함수형 인터페이스이므로 Comparator를 익명 클래스로 구현하는 대신 람다 표현식을 쓸 수 있다.
import java.util.Arrays;
public class App {
public static void main(String[] args) {
String[] names = {"eric", "kwon", "keesun"};
Arrays.sort(names, (o1, o2) -> 0);
}
}
다음은 메서드 레퍼런스를 활용한 코드를 살펴보자.
코드를 살펴보기 전에 위에서 Comparator에는 다양한 스태틱 메서드와 default 메서드가 추가되었다고 했다.
그 중 예로 사용할 메서드는 compareToIgnoreCase이다.
String을 비교하여 int값을 리턴해주는 default 메서드이다.
import java.util.Arrays;
import java.util.Comparator;
public class App {
public static void main(String[] args) {
String[] names = {"eric", "kwon", "keesun"};
Arrays.sort(names, String::compareToIgnoreCase);
System.out.println(Arrays.toString(names));
}
}
// 출력 결과
[eric, keesun, kwon]
effective java 아이템 [43]에서는 람다보다는 메서드 레퍼런스를 사용하라고 권고한다.
람다를 사용하는 가장 큰 이유는 간결함인데 이를 더 간결하게 만드는 것이 메서드 레퍼런스이다.
하지만 어떤 람다에서는 매개변수의 이름 자체가 프로그래머에게 좋은 가이드가 되기도 한다.
이런 람다는 길이는 더 길지만 메서드 참조보다 읽기 쉽고 유지보수도 쉬울 수 있다.
람다로 할 수 없는 일이라면 메서드 참조로도 할 수 없다.
그렇더라도 메서드 참조를 사용하는 편이 보통은 더 짧고 간결하므로, 람다로 구현했을 때 너무 길거나 복잡하다면 메서드 참조가 좋은 대안이 되어준다.
대표 IDE인 Intellij에서도 대체할 것을 권고하는 편인데 권고를 무조건적으로 따라야하는 것은 아니다.
예를 들어 다음 코드가 GoshThisClassNameIsHumongous라는 클래스 안에 있다고 해보자.
service.execute(GoshThisClassNameIsHumongous::action);
이를 람다로 대체하면 다음처럼 된다.
service.execute(() -> action());
메서드 참조 쪽은 더 짧지도, 더 명확하지도 않다. 따라서 람다 쪽이 더 낫다는 결론이 나온다.
같은 선상에서 java.util.function 패키지가 제공하는 제네릭 정적 팩터리 메서드인 Function.identity()를 사용하기보다는 똑같은 기능의 람다(x → x)를 직접 사용하는 편이 코드도 짧고 명확하다.
'JAVA > JAVA8' 카테고리의 다른 글
자바 8에 추가된 기술 [6] Optional (0) | 2022.02.05 |
---|---|
자바 8에 추가된 기술 [5] Stream (0) | 2022.01.23 |
자바 8에 추가된 기술 [4] deafult 메서드와 static 메서드 (0) | 2022.01.22 |
자바 8에 추가된 기술 [2] 람다 표현식 (0) | 2022.01.21 |
자바 8에 추가된 기술 [1] 함수형 인터페이스 (0) | 2022.01.21 |
- Total
- Today
- Yesterday
- 이펙티브 자바
- kotest
- BOJ
- 디자인패턴
- 클린 아키텍처
- JPA
- 정규표현식
- 객체지향
- 알고리즘
- programmers
- 디자인 패턴
- C++
- Algorithm
- Kotlin
- 백준
- AWS
- 이팩티브 자바
- Spring Boot
- kkoon9
- Java
- Spring
- node.js
- 코테
- MSA
- Olympiad
- 클린 코드
- 테라폼
- BAEKJOON
- 프로그래머스
- Effective Java
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |