자바의 람다 표현식

설명

자바의 람다 표현식이란 함수형 프로그래밍을 구성하기 위한 함수식이며,

간단히 말해 자바의 메소드를 간결한 함수 식으로 표현한 것입니다.

 

전에는 자바에서 메서드를 하나 표현하려면 클래스를 정의해야 했습니다. 하지만 람다식으로 표현하면 메서드의 이름과 반환값을 생략할 수 있고 이를 변수에 넣어 자바 코드가 매우 간결해지는 장점이 있습니다.

 

아래와 같이 int add(int a, int b) {} 메소드 표현식을 메서드 타입, 메서드 이름, 매개변수 타입, 중괄호, return 문을 생략하고, 화살표 기호를 넣음으로써 코드를 함축했음을 볼 수 있습니다.

이러한 특징으로 람다식을 이름이 없는 함수 익명 함수 라고도 합니다.

타입을 생략을 해도 컴파일러가 에러를 띄우지않는 이유는, 컴파일러 나름대로 생략된 타입 위치를 추론하여 동작하게 해주기 때문입니다.

 

함수형 인터페이스

 

그림에서도 보시다시피 아무 클래스나 추상 클래스의 메소드를 람다식으로 줄이거나 하는 행위는 못합니다.

오로지 인터페이스로 선언한 익명 구현 객체만이 람다식으로 표현이 가능하빈다. 그리고 람다 표현이 가능한 이러한 인터페이스를 가리켜 함수형 인터페이스라고 말합니다.

 

함수형 인터페이스란 딱 하나의 추상 메소드가 선언된 인터페이스를 말합니다.

위에 IAdd 인터페이스가 함수형 인터페이스 입니다.

 

생각해보면 인터페이스에 딱 하나의 메소드를 정의하는 것은 당연한 소리입니다.

인터페이스에 두개 이상 추상 메서드가 들어있으면 이를 코드로 겹쳐 표현할 방법이 달리 없기 때문에, 오로지 추상 메소드 한개만 가진 인터페이스가 람다식의 타켓 타입이 될 수 있는 것입니다.

// 함수형 인터페이스가 될 수 있다.
interface IAdd {
    int add(int x, int y);
}

// 함수형 인터페이스가 될수 없다.
interface ICalculate {
    int add(int x, int y);
    int min(int x, int y);
}

 

@FunctionalInterface

나만의 함수적 인터페이스를 만들 때 두 개 이상의 추상 메소드가 선언되지 않도록 컴파일러가 checking 해주는 기능이 있는데, 인터페이스 선언 시 @FunctionalInterface 어노테이션을 붙여주게 된다면 두 개 이상의 메소드 선언 시 컴파일 오류를 발생시켜 줍니다. 이는 개발자의 실수를 줄여주는 역할을 합니다.

@FunctionalInterface
public interface MyFunctional {
    public void method();
    public void otherMethod(); // 컴파일 오류 발생
}

 

람다식의 타입 추론

람다식으로 코드를 혁신적으로 줄일 수 있다는 점은 알았지만, 리턴 타입도 파라미터 타입도 없는 람다식을 컴파일러가 이 함수가 어떤 타입 함수인지 알고 문법을 허용하는 것일까요

 

사실 컴파일러 스스로 람다 함수식을 보고 추론하여 타입을 유추하기 때문에 가능한 것입니다.

이는 사람이 미리 정의해놓은 정의문을 보고 추론해주는 것입니다.

 

람다식 반환값 할당

일급 객체의 또다른 특징이라고 말할수 있는 메서드의 반환값을 람다함수 자체를 리턴하도록 지정 해줄 수 있습니다.

즉, 메서드의 리턴값이 메서드(함수) 인 것입니다.

interface IAdd {
    int add(int x, int y);
}

public class Main {
    public static void main(String[] args) {
        IAdd func = makeFunction(); // 메소드의 반환값이 람다 함수
        int result = func.add(1, 2);
        System.out.println(result); // 3
    }

    public static IAdd makeFunction() {
        return (x, y) -> x + y;
    }
}

 

그럼에도 불구하고

이처럼 람다표현식은 안그래도 길다란 자바 코드를 말끔히 줄이는데 상당한 일조를 하지만, 단점이나 사용하기에 적절치 못하는 경우가 존재합니다.

 

1. 람다는 문서화 할수 없다.

2. 람다는 디버깅이 다소 까다롭다.

3. stream 에서 람다를 사용할 시 for 문 보다 성능이 떨어진다.

4. 람다를 남발하면 코드가 지저분해질 수 있다.

5. 재귀로 만들경우에는 다소 부적합하다.

 

 

'Java' 카테고리의 다른 글

Java 의 Call by Value, Call by Reference  (0) 2025.01.06
간단한 에러 출력 방법과 문제점  (0) 2025.01.02
Java - Enum  (1) 2024.12.24
자바의 Optional  (0) 2024.12.23
자바의 Generic  (1) 2024.12.19