Java/함수형 인터페이스

[Java]제네릭 함수형 인터페이스(Generic Functional Interface)

DevStory 2022. 5. 10.

제네릭 함수형 인터페이스(Generic Functional Interface)란?

제네릭 함수형 인터페이스는 함수형 인터페이스의 추상 메서드에 제네릭 타입을 사용하여 모든 타입을 허용하거나 타입에 대해 제약이 존재하는 인터페이스입니다.


람다식에서 타입 설정 불가능

람다식(Lambda expression)에 매개변수의 타입과 반환 타입을 설정할 수 없습니다. 다음 예제를 통해 알아봅시다.

 

다음은 Integer 타입의 두 매개변수를 가지며, Integer 타입의 값을 반환하는 추상 메서드가 존재하는 함수형 인터페이스입니다.

@FunctionalInterface
public interface IntegerFunctionInterface {
  Integer process(Integer x, Integer y);
}

람다식을 사용하여 함수형 인터페이스를 구현할 수 있습니다.

public class Main {
  public static void main(String args[]) {
    IntegerFunctionInterface intAdd = (x, y) -> x + y;
    intAdd.process(10, 20);
  }
}

만약 다음과 같이 Integer 타입의 값이 아닌 String 또는 Double 타입의 값을 전달하면 컴파일 에러가 발생합니다.

public class Main {
  public static void main(String args[]) {
    IntegerFunctionInterface intAdd = (x, y) -> x + y;
    intAdd.process(10.5, 20);
  }
}

실행 결과

위 예제처럼 Double 타입도 처리해야 하는 경우 매개변수의 타입이 Double인 함수형 인터페이스를 추가해야 합니다.

 

아래에 소개할 제네릭 함수형 인터페이스를 사용한다면, 함수형 인터페이스는 한 개만 존재하면 됩니다.


모든 타입을 허용

매개변수의 타입과 반환 타입이 T로 동일한 경우 제네릭을 사용하여 함수형 인터페이스를 정의할 수 있습니다.

@FunctionalInterface
public interface FunctionInterface<T> {
  T process(T x, T y);
}

다음은 매개변수의 타입은 T고 반환 타입이 R인 함수형 인터페이스입니다.

@FunctionalInterface
public interface FunctionInterface<T, R> {
  R process(T x, T y);
}

이제 람다식을 사용하여 제네릭 함수형 인터페이스를 구현합니다.

public class Main {
  public static void main(String args[]) {
    // 매개변수의 타입은 Integer, 반환 타입은 Integer
    FunctionInterface<Integer, Integer> intAdd =
            (x, y) -> x + y;
    intAdd.process(10, 20);
    
    // 매개변수의 타입은 Integer, 반환 타입은 String
    FunctionInterface<Integer, String> intAdd2 =
            (x, y) -> String.valueOf(x) + String.valueOf(y);
    intAdd2.process(10, 20);
        
    // 매개변수의 타입은 String, 반환 타입은 String
    FunctionInterface<String, String> strAdd =
            (x, y) -> x + y;
    strAdd.process("Hello", " Java");
  }
}

타입 제약

제네릭 함수형 인터페이스의 타입 제약은 특정 타입으로 제한하는 것입니다.

@FunctionalInterface
public interface FunctionInterface<T extends Number> {
  T process(T x, T y);
}

이 인터페이스는 숫자 타입은 허용하지만, String 또는 사용자 정의 클래스, 숫자 타입이 아닌 클래스를 허용하지 않습니다.

 

다음은 위에서 정의한 제네릭 함수형 인터페이스를 람다식으로 구현하였으며, 컴파일 에러 없이 정상적으로 동작합니다.

public class Main {
  public static void main(String args[]) {
    FunctionInterface<Integer> intAdd = 
            (x, y) -> x + y;
            
    FunctionInterface<Double> doubleAdd = 
            (x, y) -> x + y;
  }
}

하지만, 다음 예제처럼 String 타입을 사용하는 경우 컴파일 에러가 발생합니다.

public class Main {
  public static void main(String args[]) {
    FunctionInterface<String> strAdd = 
            (x, y) -> x + y;
  }
}

실행 결과

이렇게 제네릭 함수형 인터페이스에서 타입에 대한 제약 조건을 설정할 수 있습니다.


정리

  • 제네릭 함수형 인터페이스는 제네릭으로 매개변수의 타입과 반환 타입이 정의됩니다.
  • 제네릭 타입에서 제약 조건을 설정할 수 있습니다.
반응형

댓글