Item42. 익명 클래스보다 람다를 사용하라
- 함수 객체(function object) : 추상 method를 하나만 담은 interface 의 instance (JDK1.1이전)
- 익명 class : Jdk 1.1이 등장하면서 함수 객체를 만드는데 사용됨.
1 | // 익명 class 예시 |
익명 class의 단점으로 추상 method를 하나만 구현하는데, 코드가 길어진다는 단점이 존재한다.
Lambda expression
- Functional Interface : 추상 method 를 하나만 가지고 있는 interface
1 |
|
- Lambda expression, Lambda : Function interface의 객체를 간결하게 구현할 수 있도록 지원해줌
- 람다식을 이용하면 기존에 길었던 익명 class 코드를 줄일 수 있다. (paramter 의 type 추론도 지원해줌.)
1 | Collections.sort(words,(s1,s2)->Integer.compare(s1.length(),s2.length())); |
주의사항 : compiler가 람다식의 매개변수 타입을 추론할때, generic raw type 을 사용하면 추론이 불가능해짐으로, 꼭 타입매개변수를 적어주어야 함.
- 메소드 참조 표현식 ( method reference expression )
method reference 는 람다식에서 기존에 존재하던 하나의 정적,인스턴스 method를 호출만할떄, 불필요한 매개변수를 제거하고 람다식을 더 간결하게 사용할 수 있게 해줌
(ref - https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html)
method reference 의 종류는 다음과 같다, 다음 Item 43에서 자세한 종류를 확인할 수 있다.
- Static 메소드 레퍼런스
- Instance 메소드 레퍼런스
- Constructor 메소드 레퍼런스
1 | // static method reference 사용 |
- Item34에서 소개했던 Enum 상수값별로 동작이 달라질떄 Enum type내 추상 method를 정의하고 상수별로 class 몸체를 만드는 방식도 람다를 적용하면 더 간결하게 표현이 가능하다
1 | public enum Operation { |
람다를 적용하면 다음과 같이 간결해진다.
1 |
|
Lambda 사용 주의점
이름이 없으며, 문서화가 불가능하다 따라서 동작이 명확하지 않거나, 코드가 길어지면 람다를 쓰지 않는것을 권고한다.
함수형 인터페이스에만 적용가능함으로, 그 외에는 익명class를 사용해야 한다.
this가 자기 자신이 아닌, 바깥 인스턴스를 가르킨다. 반면 익명 class는 this가 자기 자신을 가르킨다.
Jvm 구현체별로 직렬화 형태가 다를 수도 있으니, 직렬화는 하면 안된다.
외부에 있는 값을 변경하는 등 상태을 가지지 않도록 final 또는 상태를 변경하지 않는게 보장된 effectively final 이 아니면 compile error를 던져준다.
외부 상태에 의존하지 않는 다는 내용은 함수형 프로그래밍 개념의 순수 함수 개념과 관련이 있다.
- 순수 함수 (pure function ) : 함수 외부에 있는 값을 변경하지 못하는 등 상태가 없어 사이드 이펙트를 만들 수 없다.
이외에도 함수형 프로그래밍의 주요 특징은 아래와 같다.
- 고차 함수 (high-order function ) : 함수가 함수를 매개변수로 받을 수 있고 함수를 리턴할 수도 있다.
- 일급객체 (first-class object) : 함수를 일급 객체로 사용할 수 있다, 즉 함수를 변수에 할당하고, 인자로 전달할 수 있다.
- 불변성 (Immutable)