언어/JAVA

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

지나가던 개발자 2020. 4. 5. 19:21
반응형

아이템 42 : 익명 클래스보다는 람다를 사용하라

 

예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스(드물게는 추상 클래스)를 사용했다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여 특정 함수나 동작을 나타내는 데 썼다. 1997년 JDK 1.1이 등장하면서 함수 객체를 만드는 주요 수단은 익명 클래스가 되었다.

아래 코드는 문자열을 길이순으로 정렬하는데, 정렬을 위한 비교 함수로 익명 클래스를 사용한다.

 

1
2
3
4
5
Collections.sort(words, new Comparator<String>()) {
    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로 판올림되면서 작은 함수 객체를 구현하는 데 적합한 람다가 도입되었다. 익명 클래스는 (함수형 인터페이스가 아닌) 타입의 인스턴스를 만들 때만 사용하라. 람다는 작은 함수 객체를 아주 쉽게 표현할 수 있어 (이전 자바에서는 실용적이지 않던) 함수형 프로그래밍의 지평을 열었다.

반응형