개요
자바 8의 핵심 기능 중 하나인 람다 표현식과 함수형 인터페이스의 개념을 살펴본데에 이어,
@FunctionalInterface 구현체의 작성법과 생략 가능한 메서드 등을 통해서 람다 표현에 대해 익숙해진다.
또한 람다 표현식의 간소화가 어떻게, 왜 가능한지에 대해서도 확인해보자
또한, 이펙티브 자바 7장 아이템 44에서는 함수형 인터페이스를 직접 만들 경우
@FunctionalInterface 애너테이션을 반드시 사용하라고 권장한다. 그 이유는 다음과 같다.
- 의도 명확성 – 해당 인터페이스가 람다 용도로 설계되었음을 명확히 알린다.
- 컴파일러 검증 – 인터페이스가 정확히 하나의 추상 메서드만 가지도록 강제한다.
- 유지보수성 향상 – 실수로 메서드를 추가하는 것을 방지하여, 코드의 안정성을 높인다.
꼭 직접 만들어야하나? Effective Java Item 44
아이템 44에서는 람다 표현식을 활용할 때는 표준 함수형 인터페이스(Consumer<T>, Function<T,R>, Predicate<T>, Supplier<T> 등)를 최대한 활용하는 것이 좋다고 나와있다.
하지만, 표준 인터페이스가 적절하지 않은 경우에는 직접 만들어야 하고 언제 만들어야되는지에 대해서 간단히 나와있다.
1️⃣ 매개변수가 표준 인터페이스보다 더 많을 때
표준 인터페이스는 최대 2개의 매개변수(BiFunction<T, U, R> 등)만 제공하지만, 그 이상이 필요할 수도 있습니다.
2️⃣ 검사 예외(Checked Exception)를 던져야 할 때
표준 함수형 인터페이스는 throws를 지원하지 않으므로, 검사 예외를 던져야 하는 경우 직접 만들어야 합니다.
3️⃣ 특정 도메인에 특화된 기능을 제공할 때
대표적인 예가 Comparator<T>라고 한다.
표준 인터페이스인 ToIntBiFunction<T, U>로도 비교는 가능하지만, 왜 Comparator<T>가 따로 존재할까라고 질문을 던지고 있는데,
🔹 Comparator<T>가 별도의 인터페이스로 존재하는 이유
- API에서 매우 자주 사용되며, "Comparator"라는 이름이 용도를 명확하게 설명해준다.
- 비교 연산은 반드시 대칭성(transitivity)과 일관성을 유지해야 하는 규약이 있다.
- reversed(), thenComparing() 등 비교자 변환 및 조합을 위한 강력한 디폴트 메서드가 제공된다.
커스텀 @FunctionalInterface 생성
이전에 설명했다싶이,
3개 이상부터 좀 만드는 이유가 있다길래 이것저것 추가해보았다.(사실 이런건 필요없다, 예시로 든것일뿐)
여기서 이상한 점을 찾아보면
@FunctionalInterface 규칙으로 오직 하나의 추상 메서드만 가질 수 있지만 여기서는 toString(), equals() 또한 존재함을 확인 할수 있다.
오류가 나지 않는 이유는 toString()과 equals()는 사실 Object 클래스에서 기본으로 제공되므로, 추상 메서드로 간주되지 않기 때문이다.
하지만, 원래 Object 클래스에서 제공되므로, 굳이 명시할 필요 없다고 한다.
https://dzone.com/articles/java-8-functional-interfaces-sam
Java 8 — Functional Interfaces (SAM)
dzone.com
커스텀 @FunctionalInterface 구현체 생성
1️⃣ 익명클래스(람다 X)
2️⃣ 기본 람다 표현식 예제

- (String str) -> { System.out.println(str); } 형식으로 람다를 사용.
- accept()를 호출하여 실행.
3️⃣ 매개변수 타입 생략 가능
- 자바는 타입을 자동 추론하므로 (String str) 대신 (str) 만 사용 가능.
4️⃣ 매개변수와 실행문이 하나일 경우 괄호와 중괄호 생략 가능
- 매개변수와 실행문이 각각 하나일 경우, 괄호와 {} 생략 가능.
5️⃣ 리턴이 필요한 경우 return 사용

- Consumer<T>는 리턴값이 없지만, 리턴이 필요한 경우 Function<T, R>처럼 변형 가능.
- return이 필요한 경우 {}을 사용해야 함.
6️⃣ 리턴문만 있는 경우 중괄호와 return 생략 가능


- 리턴문만 있는 경우, {} 및 return 생략 가능.
+ String의 length 메서드 하나만을 실행하기 때문에 :: 연산자를 활용해서 메서드 참조하는 경우까지 적용해봤다.
'Java' 카테고리의 다른 글
해시 충돌과 참조 지역성: 자바 HashMap 성능 저하 테스트 (0) | 2025.02.19 |
---|---|
자바8 람다와 함수형 인터페이스 [3] : 디슈거링을 통한 메서드 변환과 MethodHandle, 바이트코드/JVM 분석 (1) | 2025.02.11 |
자바8 람다와 함수형 인터페이스 [1] : 람다의 등장 배경 (0) | 2025.02.11 |
JAVA 문법 QUIZ [2] (2) | 2025.02.04 |
Java 문법 QUIZ [1] (0) | 2025.02.04 |