[JAVA] @FunctionalInterface / 람다식
함수형 인터페이스
1. 추상 메서드가 정확히 하나만 존재해야 하는 인터페이스
2. default 메서드, static 메서드의 개수는 상관이 없다.
3. 모든 클래스는 Object의 자손 클래스이므로 인터페이스를 구현한 클래스는 항상 Object의 메서드를 사용할 수 있다.
-> 함수형 인터페이스에 정의된 Object의 메서드들은 함수형 인터페이스 내부의 추상 메서드 카운트에 포함되지 않음
@FunctionalInterface
특정 인터페이스에 @FunctionalInterface 어노테이션을 붙이면 컴파일러가 해당하는 인터페이스가 위의 1~3의 조건을 (함수형 인터페이스 조건)을 만족하는지를 검사해준다.
추상 메서드가 하나만 존재 -> ok
추상 메서드가 없거나, 두개 이상 존재하는 경우 -> 컴파일 에러
추상 클래스가 아닌 일반 클래스에서는 항상 Object의 메서드를 호출할 수 있다
-> Object의 메서드들은 함수형 인터페이스의 추상 메서드 개수 카운트에 포함되지 않는다.
default, static 메서드의 개수는 상관 없다.
@FunctionalInterface와 람다식
예제1 ( 람다식 )
함수형 인터페이스 TestInterface
TestProgram.java
람다식은 익명 함수라고도 불리지만 실제로는 함수형 인터페이스를 구현한 인스턴스이다.
컴파일러는TestInterface testInter= 람다식 ; 을 통해 대입될 람다식의 파라메터와 람다식 바디가 TestInterface 인터페이스의 추상 메서드(method() )의 매개변수와 리턴타입이 맞는지 체크한다.
함수형 인터페이스는 하나의 추상 메서드를 가지기 때문에 해당 추상 메서드의 시그니처와 맞는지 검사할 수 있는 것
(파라메터가 없고, 리턴타입이 void인것을 체크) <- TestInterface의 method 메서드 시그니처
( ) -> { } ;
testInter 변수에 대입된 인스턴스가 TestInterface 타입이 맞는것을 확인 할 수 있다.
(람다식의 타겟 타입이 TestInterface)
예제2 ( 람다식의 파라메터 타입 생략 )
int 타입 파라메터 두개 , 리턴타입 int
컴파일러는 선언된 인터페이스의 메서드 시그니처와 람다식 시그니처 확인
-> 람다식의 파라메터의 타입을 생략할 수 있다.
람다식의 파라메터 i,j를 선언하고( TestInterface의 method 메서드의 파라메터타입을 통해 자동으로 int, int 형이 된다)
람다식의 바디에서 i,j 변수를 사용하여 함수에 기능을 구현했다.
예제3 ( 람다식 파라메터가 하나일때만 () 생략 가능)
예제4 ( 람다식 바디가 한 표현식이면 { }를 생략가능 )
{}; 의 {}를 생략하면 람다식의 바디인것을 알려줘야하기 때문에 마지막에 ;를 붙여야한다.
리턴타입이 없는 경우 람다식 바디의 {}를 생략할 경우
println메서드의 ; 가 변수 대입문의 ; 이다
아래를 참고
타입 추론에 대해서
컴파일러는 람다식의 타겟 타입을 Object로 적용한다.
Object는 함수형 인터페이스가 아니므로 컴파일 에러가 난다.
-> 컴파일러에게 타겟 타입을 (TestInterface)로 적용하라고 알려준다.