익명 클래스의 등장
예전에는 자바에서 함수 타입을 표현할 때 추상 메서드를 하나만 담은 인터페이스를 사용했다. 이런 인터페이스의 인스턴스를 함수 객체라고 하여, 특정 함수나 동작을 나타내는 데 썼다. 이런 익명 클래스는 이후에 함수 객체를 만드는 주요 수단이 되었다.
Collections.sort(words, new Comparator<String>() {
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
}
이런 익명 클래스 방식은 코드가 너무 길기 때문에 자바는 함수형 프로그래밍에 적합하지 않다.
람다식
자바 8부터 추상 메서드 하나짜리 인터페이스는 특별한 의미를 인정받아 인스턴스를 람다식을 사용해 만들 수 있게 되었다. 람다는 함수나 익명 클래스와 개념은 비슷하지만 코드는 훨씬 간결하다.
Collections.sort(words, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
람다식에서는 컴파일러가 문맥을 살펴 타입을 추론해준다. 만약 컴파일러가 추론하지 못한다면 이때는 타입을 명시해주면 된다. 람다 자리에 비교자 생성 메서드를 사용하면 이 코드를 더 간결하게 만들 수 있다.
Collections.sort(Words, comparingInt(String::length));
자바 8에서 List 인터페이스에 추가된 sort메서드를 이용하면 더 짧아진다.
words.sort(comparingInt(String::length));
람다식과 제네릭
람다식을 사용할 때 컴파일러는 타입 추론을 하는데 필요한 정보를 제네릭에서 얻는다. 따라서 List와 같은 로 타입은 사용하지 않아야 한다.
List<String>이 아닌 List로 되어있었다면 컴파일 오류가 났을 것이다.
람다의 단점
- 람다는 이름이 없고 문서화가 불가능하다. 따라서 코드 자체로 동작이 명확히 설명되지 않거나 코드 줄 수가 많아지면 람다를 쓰지 말아야 한다.
- 람다는 한 줄일 때 가장 좋고 길어야 세 줄 안에 끝내는 게 좋다.
- 람다는 자신을 참조할 수 없다. 즉, this키워드는 바깥 인스턴스를 가리킨다.
-> 만약 인스턴스 자신을 가리켜야 한다면 익명 클래스를 사용하면 된다. - 람다도 익명 클래스처럼 직렬화 형태가 가상머신별로 다르기 때문에 직렬화하는 일은 삼가야 한다.