함수형 인터페이스(FunctionInterface) - 자바8

1. 함수형 인터페이스 표준 API

  • 함수형 인터페이스는 추상 메서드가 1개만 정의된 인터페이스를 통칭하여 일컫는다. 이 인터페이스의 목적은 자바에서 람다 표현식을 이용해 함수형 프로그래밍을 구현하기 위해서이다.

  • 그런데 생각해보면, 함수의 시그니처는 다양하다.

    • 함수의 리턴 값이 있을수도 없을수도 있고,

    • 매개변수 갯수가 1,2 개 일 수 있다.

  • 이러한 형태의 함수를 일일이 정의해서 사용하기엔 너무 양이 많으니, 자바 개발진들이 미리 함수형 인터페이스를 만들어 제공하는 것이 바로 함수형 인터페이스이다.

// @FunctionalInterface 어노테이션을 붙여주면, 
// 두 개 이상의 메서드 선언 시 컴파일 오류를 발생시킨다. 
@FunctionalInterface
public interface Animal {
    public void method(); 
}

자바에서 자주 사용하는 자료구조를 컬렉션 프레임워크로 만들어 제공하듯,

자주 사용할 것 같은 람다 함수 형태를 함수형 인터페이스 표준 API 로 미리 만들어 제공한다고 이해하자.

1.1. 표준 API 종류

  • 함수형 인터페이스 표준 API 는 java.util.function 패키지로 제공된다. 이 패키지 안에 있는 함수형 인터페이스 종류로는 Consumer, Supplier, Function, Operator, Predicate 가 있다.

  • 이 인터페이스명은 각 함수의 형태와 목적에 따라 조금 재미있기 붙여진 이름으로 뒤에서 다룬다.

  • 이처럼 다양한 함수 형태를 정리해 API 로 제공하므로, 개발자들이 굳이 추상 메서드 하나 가진 인터페이스를 일일히 정의할 필요가 없고, API 를 사용하기만 하면 된다.

1.2. 표준 API 는 타입 제공 용도이다.

  • 자바스크립트의 경우 약타입 언어이기 때문에, 다음과 같이 변수에 함수를 대입만 하면 알아서 타입이 추론이 된다.

  • 하지만 자바는 강타입 언어이기 때문에, 정수면 정수에 맞는 타입을, 함수면 함수에 맞는 타입을 지정해주어야 한다. (자바의 람다식을 변수나 매개변수에 할당하기 위해서는 그에 해당하는 인터페이스 타입이 필요하다)

  • 람다 표현식 or 익명 클래스는 함수형 인터페이스의 구현을 제공하는 방식으로, Java 에서는 람다 표현식을 사용할 때 그것을 담기 위한 타입으로 함수형 인터페이스를 사용한다.

  • 그런데 함수형 인터페이스라고 하지만 사실상 인터페이스 명이 딱히 정해져 있지 않기 때문에, 문제가 발생한다. (그냥 추상 메서드 한개만 가지고 있으면 모든 인터페이스는 함수형 인터페이스로 취급될 수 있기 때문이다)

  • 이것은 설계할 때 애매한 문제를 발생시키는데, 만일 파라미터로 람다 함수를 받는 어떠한 메서드를 설계한다고 하면, 이 매개변수의 인터페이스 타입명을 지정하는데 애로사항이 생긴다.

  • 따라서 자바 개발진들이 미리 함수형 인터페이스 이름들을 정해 제공하는 것이 위의 표에서 본 Runnable, Consumer, Supplier, Function, Operator, Predicate 인터페이스인 것이다.

1.2.1. Runnable 인터페이스

  • 함수형 인터페이스와 람다 함수를 이해하는데 있어 가장 좋은 것이 바로 Runnable 인터페이스이다.

  • 실제 자바 패키지에 정의 되어있는 Runnable 인터페이스 선언 코드를 살펴보면 다음과 같이 선언되어 있다.

  • 뭘 달린다 or 실행한다는 의미인 것 같은데, 이러한 인터페이스의 용도가 무엇인지 직관적으로 알기에는 애매모호하다.

  • 앞서 말했듯 함수형 인터페이스를 만든 이유는 람다 함수의 타입명을 미리 지정하기 위해서이다.

    • 즉 매개변수를 받지도 않고 리턴값이 없고 그냥 실행만 하는 람다 함수 형태를 받는 메서드를 설계할 때 람다 매개변수의 인터페이스 타입을 Runnable 로 설정하면 되는 것이다.

    • 그리고 이 메서드가 바로 우리가 잘 아는 Thread 클래스의 메서드(생성자) 이다.

  • 실제로 Thread 생성자 매개변수로 Runnable 타입의 target 을 받는 것을 확인할 수 있다.

  • 이것이 바로 함수형 인터페이스의 존재 이유이다. Runnable 이외에도 자주 사용하는 형식의 타입으로 정의한 함수형 인터페이스를 통해서 람다식을 매개변수로 사용할 수 있다.

2. 함수형 인터페이스 API 사용법

2.1. Consumer 인터페이스

2.1.1. Consumer 종류

2.2. Supplier 인터페이스

2.2.1. Supplier 종류

2.3. Function 인터페이스

2.3.1. Function 종류

Last updated