아이템 42 : 익명 클래스보다는 람다를 사용하라
예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스(드물게는 추상 클래스)를 사용했다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여 특정 함수나 동작을 나타내는 데 썼다. 1997년 JDK 1.1이 등장하면서 함수 객체를 만드는 주요 수단은 익명 클래스가 되었다.
아래 코드는 문자열을 길이순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스를 사용한다.
1
2
3
4
5
|
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
Colored by Color Scripter
|
아래 코드는 람다 방식으로 바꾼 코드이다.
1
|
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
|
여기서 람다, 매개변수(s1, s2), 반환값의 타입은 각각 (Comparator<String>), String, int지만 코드에서는 언급이 없다. 컴파일러가 문맥을 살펴 타입을 추론해준 것이다. 상황에 따라 컴파일러가 타입을 결정하지 못할 수도 있는데, 그럴 때는 프로그래머가 직접 명시해야 한다.
타입을 명시해야 코드가 더 명확할 때만 제외하고는, 람다의 모든 매개변수 타입은 생략하자. 그런 다음 컴파일러가 "타입을 알 수 없다"는 오류를 낼 때만 해당 타입을 명시하면 된다.
메서드나 클래스와 달리, 람다는 이름이 없고 문서화도 못 한다. 따라서 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야 한다.
람다도 익명 클래스처럼 직렬화 형태가 구현별로 다를 수 있다. 따라서 람다를 직렬화하는 일은 극히 삼가야 한다. 직렬화해야만 하는 함수 객체가 있다면 private 정적 중첩 클래스의 인스턴스를 사용하자.
핵심 정리
자바가 8로 판올림되면서 작은 함수 객체를 구현하는 데 적합한 람다가 도입되었다. 익명 클래스는 (함수형 인터페이스가 아닌) 타입의 인스턴스를 만들 때만 사용하라. 람다는 작은 함수 객체를 아주 쉽게 표현할 수 있어 (이전 자바에서는 실용적이지 않던) 함수형 프로그래밍의 지평을 열었다.
'언어 > JAVA' 카테고리의 다른 글
[Effective Java] 람다보다는 메서드 참조를 사용하라 (0) | 2020.04.06 |
---|---|
[Effective Java] 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2020.04.04 |
[Effective Java] @Override 애너테이션을 일관되게 사용하라 (0) | 2020.04.02 |
[Effective Java] 명명 패턴보다 애너테이션을 사용하라 (0) | 2020.04.01 |
[Effective Java] 확장할 수 있는 열거 타입이 필요하면 인터페이스를 사용하라 (0) | 2020.03.31 |