계속해서 람다에 대한 포스팅을 하고 있습니다. 


람다 표현식의 사용을 통해 우리는 함수형 인터페이스의 인스턴스를 만들 수 있다는 것을 알게 되었습니다.



그러나 사실 람다표현식만 보게 되면 어느 함수형 인터페이스를 구현하는지에 대한 정보는 없습니다. 

단지 함수형 인터페이스에서 구현할 함수 디스크립터와의 형식 검사를 통해 유효성을 가질 수 있으며, 또한 어떻게 보면 추론까지 가능합니다. 


오늘은 이러한 내용에 대해 포스팅을 하려 합니다. ㅡㅡ^


1. 형식 검사


일단 아래 코드를 먼저 보도록 하겠습니다.


1
2
3
4
5
6
7
@FunctionalInterface
public interface Predicate<T> {
    boolean test(T t);
}
 
Predicate<Apple> predicate = (Apple a) -> "green".equals(a.getColor());
 
cs


람다 표현식 (Apple a) -> "green".equals(a.getColor()); 이 Predicate<Apple>에 대입은 test 라는 한 개의 추상 메소드에 대한 함수 디스크립터에서 묘사해야할 내용과 같음을 알 수 있습니다. 


즉 추상 메소드의 시그니처가 요구하는 요구사항을 맞춰 람다를 제작해주어야 합니다.


이 때, void 의 경우 특별한 호환 규칙이 존재합니다.


1
2
3
4
5
6
public boolean checkData(Integer a){
    return a != null;
}
 
Consumer<Integer> setData = (Integer a) -> checkData(a);
setData.accept(5);
cs


위의 예제의 경우 람다 표현식 (Integer a) -> checkData(a); 의 경우 Integer를 파라미터로 받아 boolean 을 출력함을 알 수 있습니다. 


하지만 이 것은 유효한 코드입니다. 

(프로시저에서 boolean 함수를 사용한 것과 비슷하다고 생각하면 자연스럽게 넘어갈 수 있는 문제인 것 같습니다. ㅡㅡ^)


2. 형식 추론


함수형 인터페이스가 선언된 대상 형식(ex. Consumer<Apple>)에 따라, 람다 표현식의 형식 추론을 할 수 있습니다. 

대상 형식을 통해 함수 디스크립터(ex. (Integer a) -> a +2)를 알 수 있으며, 다음과 같은 코드가 가능합니다.


1
Consumer<Integer> setData = (a) -> checkData(a) ;
cs


대상형식 Consumer<Integer> 에 의해 람다 파라미터 부분에 Integer 형태가 이미 들어갈 것이라는 것을 추론할 수 있으며, 그렇기 때문에 단순히 a를 쓰는 것으로 대체가 가능합니다.


우리는 이미 이런 것을 제네릭을 사용하면서 많이 봐왔습니다. 

아래와 같이 말이죠.


1
List<Integer> dataList = new ArrayList<>();
cs



자바 8 인 액션
국내도서
저자 : 라울-게이브리얼 우르마(RAOUL-GABRIEL URMA),마리오 푸스코(MARIO FUSCO),앨런 마이크로프트(ALAN MYCROFT) / 우정은역
출판 : 한빛미디어 2015.04.01
상세보기



반응형

'개발이야기 > 함수형 프로그래밍' 카테고리의 다른 글

람다 조합  (0) 2016.08.02
메서드 레퍼런스  (0) 2016.08.01
클로저와 람다  (2) 2016.07.28
원시타입을 위한 함수형 인터페이스  (0) 2016.07.28
JAVA8 에 정의된 함수형 인터페이스  (0) 2016.07.28
Posted by N'