item 44) 표준 함수형 인터페이스를 사용하라

함수형 인터페이스

  • 과거에 주로 사용하던 템플릿 메서드 패턴보다는 함수 객체를 매개변수로 받는 정적 팩토리나 생성자를 제공해야 한다.

  • 자바 표준 라이브러리에 이미 정의해둔 표준 함수형 인터페이스가 담겨있으므로 필요한 용도에 맞는게 있다면 활용하자.

  • java.util.function 패키지에는 총 43개의 인터페이스가 담겨있다. 기본 인터페이스 6개만 기억하면 나머지를 충분히 유추해서 사용할 수 있다.

  • Operator: 반환값과 인수 타입이 같은 함수를 의미, 인자의 개수에 따라 Unary, Binary로 나뉜다.

  • Predicate: 인수 하나를 받아 boolean을 반환

  • Function: 인수와 반환 타입이 다른 함수

  • Supplier: 인수를 받지 않고 값을 반환하는 함수

  • Consumer: 인수를 하나 받고 반환값은 없는 함수

  • 기본 타입인 int, long, double마다 변형된 인터페이스가 존재한다. ex) Predicate -> IntPredicate, DoublePredicate, ..

  • Function 인터페이스의 경우 입력과 결과의 타입이 항상 다르므로 기본 타입 -> 기본타입의 경우 6개의 변형이 있고, 객체 참조 -> 기본타입의 경우 3개의 변형이 있다.

  • 대부분은 기본 타입만 지원하지만 기본 함수형 인터페이스에 박싱된 기본 타입을 넣지는 말 것.

전용 함수형 인터페이스

  • 표준 함수형 인터페이스가 아닌 필요한 용도에 맞도록 직접 작성하는 인터페이스

  • 1) API에서 자주 쓰이며, 이름 자체가 용도를 명확히 설명해주거나 2) 반드시 따라야 하는 규약이 있거나 3) 유용한 디폴트 메서드들을 제공한다면 전용 함수형 인터페이스의 구현을 고민해봐야 한다.

@FunctionalInterface

  • 직접 만든 함수형 인터페이스에 프로그래머의 의도를 명시하고자 사용

  • 해당 클래스의 코드나 설명 문서를 읽을 이에게 그 인터페이스가 람다용으로 설계된 것을 알려준다.

  • 해당 인터페이스가 추상 메서드를 오직 하나만 가지고 있어야 컴파일되게 해준다.

  • 유지보수 과정에서 누군가 실수로 메서드를 추가하지 못하게 막아준다.

주의할 점

  • 서로 다른 함수형 인터페이스를 같은 위치의 인수로 받는 메서드들을 다중 정의해서는 안된다. 클라이언트에게 불필요한 모호함을 안겨준다.

  • ex) Executor의 submit 메서드는 Callable<T>를 받는 것과 Runnable을 받는 것을 다중정의했기 때문에 올바른 메서드를 알려주기 위해 형변환해야 할 때가 종종 생긴다.

Last updated