람다의 실제 형식
계속해서 람다에 대한 포스팅을 하고 있습니다.
람다 표현식의 사용을 통해 우리는 함수형 인터페이스의 인스턴스를 만들 수 있다는 것을 알게 되었습니다.
그러나 사실 람다표현식만 보게 되면 어느 함수형 인터페이스를 구현하는지에 대한 정보는 없습니다.
단지 함수형 인터페이스에서 구현할 함수 디스크립터와의 형식 검사를 통해 유효성을 가질 수 있으며, 또한 어떻게 보면 추론까지 가능합니다.
오늘은 이러한 내용에 대해 포스팅을 하려 합니다. ㅡㅡ^
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 |
|
'개발이야기 > 함수형 프로그래밍' 카테고리의 다른 글
람다 조합 (0) | 2016.08.02 |
---|---|
메서드 레퍼런스 (0) | 2016.08.01 |
클로저와 람다 (2) | 2016.07.28 |
원시타입을 위한 함수형 인터페이스 (0) | 2016.07.28 |
JAVA8 에 정의된 함수형 인터페이스 (0) | 2016.07.28 |