티스토리 뷰
728x90
반응형
표준 함수형 인터페이스를 사용하라
- 자바가 람다를 지원하면서 상위 클래스의 기본 메서드를 재정의 후 원하는 동작을 구현하는 템플릿 메서드 패턴의 매력이 크게 줄었습니다. 이를 대체하는 현대적인 해법은 같은 효과의 함수 객체를 받는 정적 팩토리나 생성자를 제공하는 것입니다.
- 위 말을 조금 풀어서 설명하자면, 함수 객체를 매개변수로 받는 생성자와 메서드를 더 많이 만들어야하며, 이때 함수형 매개변수 타입을 올바르게 선택해야 합니다.
💡 함수형 인터페이스
- 아래 함수형 인터페이스는 잘 동작하지만 굳이 사용할 필요가 없습니다. 자바 표준 라이브러리에는 이미 같은 모양의 인터페이스가 준비되어 있기 때문입니다.
- java.util.function 패키지에는 다양한 용도의 표준 함수형 인터페이스가 있습니다.
@FunctionalInterface
public interface EldestEntryRemovalFunction<K, V> {
boolean remove(Map<K, V> map, Map.Entry<K, V> eldest);
}
💡 표준 함수형 인터페이스
- java.util.function 패키지 내부에는 다양한 용도의 표준 함수형 인터페이스가 담겨 있습니다. 그래서 굳이 개발자가 직접 함수형 인터페이스를 구현하기보단 제공되는 표준 함수형 인터페이스를 사용하는게 좋습니다.
인터페이스 | 함수 시그니처 | 예시 |
UnaryOperator<T> | T apply(T t) | String::toLowerCase |
BinaryOperator<T> | T apply(T t1, T t2) | BigInteger::add |
Predicate<T> | boolean test(T t) | Collection::isEmpty |
Function<T> | R apply(T t) | Arrays::asList |
Supplier<T> | T get() | Instant::now |
Consumer<T> | void accept(T t) | System.out::println |
- Operator 인터페이스는 인수가 1개인 UnaryOperator와 인수가 2개인 BinaryOperator로 나뉘며, 반환값과 인수의 타입이 같은 함수를 의미합니다.
- Redicate 인터페이스는 인수 하나를 받아 boolean을 반환하는 함수를 의미합니다.
- Function 인터페이스는 인수와 반환타입이 다른 함수를 의미합니다.
- Supplier 인터페이스는 인수를 받지 않고 값을 반환(혹은 제공)해주는 함수를 의미합니다.
- Consumer 인터페이스는 인수를 하나 받고 반환값은 없는, 인수를 소비하는 함수를 의미합니다.
💡 표준 함수형 인터페이스를 사용해야 하는 경우는?
- 표준 함수형 인터페이스 대부분은 기본 타입(Primitive)만 지원합니다. 그렇다고 기본 함수형 인터페이스에 박싱된 기본 타입(Wrapper Class)을 넣어 사용하지 않도록 합니다.
- 계산시 오토 박싱과 언박싱이 발생하여 성능이 느려집니다. https://kdg-is.tistory.com/339 참고
- 표준 인터페이스 중 필요한 용도에 맞는게 없다면 직접 작성해야하며, 구조적으로 똑같은 표준 함수형 인터페이스가 있더라도 직접 작성해야하는 경우도 있습니다.
💡 직접 작성하는 경우
- Comparator<T> 인터페이스의 경우, 구조적으로 ToIntBiFunction<T, U>와 동일하지만 독자적인 인터페이스로 존재하는 이유가 있습니다.
- 이유 1 - 사용 빈도가 높으며, 이름 자체로 용도를 명확히 설명해줍니다.
- 이유 2 - 구현하는 쪽에서 반드시 지켜야할 규약을 담고 있습니다.
- 이유 3 - 비교자들을 변환하고 조합해주는 유용한 디폴트 메시지를 가지고 있습니다.
💡 @FunctionalInterface
- 이 애노테이션은 인터페이스가 함수형 인터페이스로 사용됨을 알려주는 애노테이션입니다.
- 자체적으로 어떤 특별한 동작을 수행하는 것은 아닙니다. 그렇기 때문에 해당 애노테이션 없이도 인터페이스가 하나의 추상 메서드만 가진다면 정상적으로 동작합니다. 하지만 이 애노테이션을 사용하는 이유는 @Override 애노테이션을 사용하는것과 동일합니다.
프로그래머에게 의도를 명시하는 목적을 가지고 있습니다.- 해당 클래스의 코드나 설명 문서를 읽을 이에게 해당 인터페이스가 람다용으로 설계된 것을 알려줍니다.
- 해당 인터페이스가 추상 메서드를 오직 하나만 가지고 있어야 컴파일 됩니다.
- 유지보수 중 누군가 실수로 메서드를 추가하지 못하게 방지해줍니다.
- 이러한 이유로 함수형 인터페이스를 직접 만들 경우에는 @FunctionalInterface 애노테이션을 사용하는게 좋습니다.
728x90
반응형
'스터디 > 이펙티브 자바' 카테고리의 다른 글
이펙티브 자바 - Item46. 스트림에서는 부작용 없는 함수를 사용하라 (0) | 2022.07.31 |
---|---|
이펙티브 자바 - Item45. 스트림은 주의해서 사용하라 (0) | 2022.07.31 |
이펙티브 자바 - Item43. 람다보다는 메서드 참조를 사용하라 (0) | 2022.07.30 |
이펙티브 자바 - Item42. 익명클래스 보다는 람다를 사용하라 (0) | 2022.07.30 |
이펙티브 자바 - Item41. 정의하려는 것이 타입이라면 마커 인터페이스를 사용하라 (0) | 2022.07.29 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- polling publisher spring boot
- java userThread와 DaemonThread
- spring boot excel download paging
- 공간 기반 아키텍처
- JDK Dynamic Proxy와 CGLIB의 차이
- redis 대기열 구현
- 트랜잭셔널 아웃박스 패턴 스프링부트
- transactional outbox pattern spring boot
- 레이어드 아키텍처란
- microkernel architecture
- 서비스 기반 아키텍처
- redis sorted set으로 대기열 구현
- transactional outbox pattern
- java ThreadLocal
- spring boot redisson sorted set
- spring boot excel download oom
- spring boot redisson 분산락 구현
- spring boot 엑셀 다운로드
- @ControllerAdvice
- 자바 백엔드 개발자 추천 도서
- spring boot redis 대기열 구현
- 트랜잭셔널 아웃박스 패턴 스프링 부트 예제
- service based architecture
- spring boot poi excel download
- space based architecture
- pipeline architecture
- 람다 표현식
- spring boot redisson destributed lock
- pipe and filter architecture
- redis sorted set
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함