함수형 인터페이스는 구현부가 작성되지 않은 추상 메서드를 1개만 갖는 인터페이스를 말하고,
인터페이스에 있는 추상메서드의 파라미터와 반환타입이 일치하는 람다식을 참조할 수 있다.
example.
Runnable functionalInterface = () -> System.out.println("Hello!");
Java
복사
함수형 인터페이스란 1개의 추상 메서드를 갖는 인터페이스를 말한다.
참고로 인터페이스 내에 여러개의 static · default 메서드가 있는 것은 상관없다.
@FunctionalInterface 어노테이션을 붙여주면 추상 메서드가 하나인지 검사를 해주는데, 인터페이스 검증과 유지보수를 위해 붙여주는 것이 좋다.
사실, Java에서 제공하는 함수형 인터페이스로도 충분해서, 직접 함수형 인터페이스를 만들 일은 거의 없긴 하다.
람다식은 독자적으로 쓰일 수 없기 때문에, 참조변수를 통해서 호출할 수 있어야 한다.
람다식을 연결해주는 객체가 필요한데, 추상메서드를 가진 인터페이스를 구현받아 사용하는 방식이 기존 자바의 규칙을 어기지 않으면서 자연스러운 방식이기 때문이다.
즉, 람다식을 다루기 위한 추상 메서드를 1개만 가진 인터페이스를 함수형 인터페이스 라고 부른다.
함수형 인터페이스의 원리에 대해서 살펴보자.
람다식이 추가되기 전과 후의 차이
public interface Sample {
void print();
}
public class Excercise {
public static void main(String[] args) {
// 익명 클래스 생성 후, 추상 메서드를 구현하여 사용
Sample sample = new Sample() {
@Override
public void print() {
System.out.println("안녕");
}
};
sample.print();
// 람다식을 사용하여 구현부를 작성하고 사용
// (단, 람다식의 반환값이 인터페이스의 메서드 반환 타입과 일치해야하고 인터페이스는 메서드가 하나만 있어야한다.)
Sample sample2 = () -> System.out.println("안녕");
sample2.print();
}
}
Java
복사
람다식이 등장하기 이전에는 모든 메서드는 클래스에 포함되어야 하므로 클래스를 새로 만들고, 새로 만든 클래스에 메서드를 만든 뒤 객체를 생성해야만 메서드를 호출할 수 있었다.
하지만 람다식은 람다식 자체만으로 메서드의 역할을 대신할 수 있다.
단, 람다식의 반환값이 인터페이스의 메서드 반환 타입과 일치해야하고 인터페이스는 메서드가 하나만 있어야한다.
람다식이 객체(참조변수)에 연결될 수 있는 조건
public interface Sample {
// 추상메서드 1
void print();
// default 메서드
default void defaultPrint(){
System.out.println("default Print!!");
}
// static 메서드
static void staticPrint2(){
System.out.println("static Print!!");
}
// 추상메서드가 2개인 경우 에러 발생!!
// void print2();
}
public class Excercise {
public static void main(String[] args) {
// 추상 메서드가 1개라면 정상 동작
Sample sample2 = () -> System.out.println("안녕");
sample2.print();
}
}
Java
복사
위 경우에서 Sample interface에 추상 메서드가 1개라면 람다식으로 대체가 가능하지만,
추상 메서드가 2개면 람다식과 1:1로 연결될 수 없어 컴파일 에러가 발생한다.
람다식은 메서드 파라미터로도 활용 가능!
Sample sample = () -> System.out.println("안녕");
Plain Text
복사
위와 같이 함수 인터페이스에 람다식을 할당했다.
이 원리를 생각하면, 파라미터로 넘기는 방법도 쉽게 떠올릴 수 있다.
람다식을 특정 메서드의 파라미터로 넘기는 방법은 다음과 같다.
public interface Sample {
void print();
}
public class Excercise {
public static void main(String[] args) {
lambdaParameterMethod(()-> System.out.println("람다식 넘겨주기!"));
lambdaParameterMethod(returnLambda());
}
public static void lambdaParameterMethod(Sample sample) {
sample.print();
}
public static Sample returnLambda(){
return () -> System.out.println("람다식 반환!!");
}
}
Java
복사
lambdaParameterMethod() 메서드는 파라미터로 Sample을 입력받는다.
따라서, void 반환을 하는 람다식은 모두 파라미터로 입력될 수 있을 것이다.
또한, returnLambda()는 반환타입이 Sample이므로, void 반환을 하는 람다식을 반환할 수 있을 것이다.
정리해보면 위와 같다.
자바가 제공하는 함수형 인터페이스
void 반환, boolean 반환, 객체 반환 등등 다 웬만한 것들은 다 정의되어 있으므로, 사용하면 된다.
다만, 매개변수가 3개 이상인 것들은 따로 함수형 인터페이스를 정의해서 사용해야한다.