본문 바로가기
👨‍💻 프로그래밍/📦 Backend

@FunctionalInterface란?

by 개발자 진개미 2025. 1. 30.
반응형

어떤 때 쓰는 걸까?

interface인데 Abstract Method가 딱 1개 있는 경우

 

Abstract Method가 1개인게 왜 중요할까요? Abstract Method가 1개이면 interface를 구현하는 class를 직접 만들지 않고 여러 간결한 문법들을 써서 변수에 interface를 구현하는 값을 바로 할당할 수 있기 때문입니다. 예를 들면...

  1. Lambda 식
  2. Method Reference

 

실제로 유용한 예시는 아니지만 String을 조작하기 위해 interface를 만든다고 해 보겠습니다.

@FunctionalInterface
interface StringTransformer {
    String transform(String input);
}

🐜 Lambda 식

@FunctionalInterface가 있기 때문에 Interface를 구현하는 class를 만들지 않고 바로 Lambda 식을 할당할 수 있습니다.

StringTransformer toUpperCase = input -> input.toUpperCase();

 

🐜 Method Reference

비슷하게 Method Reference를 써서 바로 할당할 수 있습니다.

StringTransformer toUpperCase = String::toUpperCase;

 


@FunctionalInterface가 아닌데 쓰면 어떻게 될까?

Compile Error

@FunctionalInterface는 실제로 유용할까?

솔직히 잘 쓰이지는 않습니다. 제가 현업에서 구른 1년 6개월 동안 코드에서는 1번도 보지 못했고, Spring 코드를 까면서 보기 시작한 최근 몇 개월에 많이 보게 됐습니다. 하지만 @FunctionalInterface를 직접 만들지는 않더라도 간접적으로 쓰는 경우는 많습니다.

🐜 JDBC의 RowMapper

List<User> users = jdbcTemplate.query(
    "SELECT * FROM users",
    (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name"))
);

2번째 Argument를 보면 생각없이 썼지만 RowMapper interface를 구현하는 건데 새로운 Class를 만들지 않고 바로 Lambda로 만들고 있습니다. @FunctionalInterface입니다!

 

🐜 Spring Boot의 ApplicationRunner, CommandLineRunner

@Bean
public ApplicationRunner initRunner() {
    return args -> System.out.println("Application started!");
}

비슷하게 Application Runner도 분명 interface인데 새로운 class를 만들어서 구현하는 게 아니라 바로 Lambda를 넘겨주고 있습니다. @FunctionalInterface가 없었다면 불가능한 일입니다.

package org.springframework.boot;

@FunctionalInterface
public interface CommandLineRunner {
    void run(String... args) throws Exception;
}

 

🐜 Spring MVC의 HandlerInterceptor

HandlerInterceptor loggingInterceptor = (request, response, handler) -> {
    System.out.println("Request received: " + request.getRequestURI());
    return true;
};

Kotlin에서는 어떻게 사용될까?

Kotlin에도 비슷한 개념이 있습니다. 문법은 조금 다르지만요...

fun interface IntPredicate {
    fun accept(i: Int): Boolean
}

위와 같이 fun interface를 쓰면 이걸 Function Interface라고 지정할 수 있습니다. 그럼 아래와 같이 하는 게 아니라...

val isEven = object : IntPredicate {
   override fun accept(i: Int): Boolean {
       return i % 2 == 0
   }
}

더 간편하게 아래와 같이 할 수 있습니다!

val isEven = IntPredicate { it % 2 == 0 }

 

 

Functional (SAM) interfaces | Kotlin

 

kotlinlang.org


참고

 

FunctionalInterface (Java Platform SE 8 )

An informative annotation type used to indicate that an interface type declaration is intended to be a functional interface as defined by the Java Language Specification. Conceptually, a functional interface has exactly one abstract method. Since default m

docs.oracle.com


반응형