파라미터로 값이 아닌 '코드'를 넘겨야 하는 순간이 있다. 이때 사용하는 기술이 '동적 파라미터화'이다. '람다'가 등장하기 전에는 동적 파라미터화는 무겁게 구현되었다.
1) 구현객체 넘기기
List<Apple> result1 = getFilteredApples(apples,new ColorPredicate()); // new ColorPredicate() 구현객체 넘기기
List<Apple> result2 = getFilteredApples(apples,new ColorPredicate()); // new ColorPredicate() 구현객체 넘기기
위와 같이, '코드'를 포함한 구현객체를 파라미터로 넣는 방법이 있고
2) 익명클래스 사용
//Runnable 익명클래스 넘기기
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable 객체 실행!");
}
});
run() 메소드를 가진 익명 클래스를 파라미터로 넘길 수도 있다. 1), 2)는 넘기고 싶은 코드를 메소드로 갖는 객체를 생성하여 파라미터로 넘겼지만.... 지저분하다.
그래서 등장한 방법이 '람다(Lambda)'이다.
코드를 넘긴다?
//Runnable 익명클래스 넘기기
Thread t = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Runnable 객체 실행!");
}
});
Thread 클래스는 Runnable 객체를 파라미터로 받아서 run을 정의한다. Thread 클래스의 run 메소드를 직접 사용하지 않고 Runnable 객체를 파라미터로 받아 정의하는 이유는 재사용 가능하도록 만들기 위함이다.
Thread의 run 로직은 언제든 요구사항에 따라 변경될 수 있다. 변경이 될때 마다 새로 Thread 클래스를 생성하는 것은 비효율이다. 그래서 덩치가 큰 Thread 클래스가 아닌 run() 메소드 하나만 가지고 있는 함수형인터페이스인 Runnable을 생성하여 파라미터로 넣어주는 방식으로 구현된다. 정리하면, run 메소드는 Thread로 넘기고 싶은 소스코드이고 Runnable 객체는 run 메소드를 담는 '그릇'이다.
고로, 소스코드를 넘긴다란? 소스코드를 담은 그릇, 즉 '객체'를 넘기는 것이다.
람다란?(Lambda)
람다도 마찬가지이다. 표현식은 단순화되었지만 결국은 '객체'를 넘기는 것이다.
Runnable runnable = () -> System.out.println("Hello World!");
람다는 단 '한 개'의 메소드를 표현한다. [ () -> System.out.println("Hello World!"); ]
그리고 람다는 객체를 반환한다.
고로, 람다가 반환하는 객체는 메소드가 단 하나뿐인 함수형인터페이스의 구현객체이다.
Runnable은 run 메소드 하나만 가지고 있다. 그러므로 () -> System.out.println("Hello World!"); 이런 람다표현식이 있을때, 자동으로 ()는 run 메소드의 인수, System.out.println("Hello World!")는 run 메소드 처리내용으로 매핑된다.
람다가 표현하는 함수형인터페이스의 단 한개의 메소드를 두고 '시그니쳐(Signature)'라 부르고 시그니쳐를 서술하는 람다표현식의 메소드를 '함수디스크립터'라 부른다.
정리하면 람다란, 인수로 넘길 함수형인터페이스 객체를 정의하기 위해, 함수형인터페이스의 시그니쳐를 서술한 함수디스크립터를 가지고 있는 표현식이라 할 수 있다. 고로, 람다는 함수형 인터페이스를 파라미터로 갖는 메소드에만 사용가능하다.
// Thread 클래스의 생성자는 Runnable 함수형인터페이스를 인수로 가짐으로 람다표현식 사용가능
Thread thread = new Thread(() -> System.out.println("Hello World!"));
참고자료
'JAVA > Modern JAVA' 카테고리의 다른 글
[MODERN JAVA] 람다(Lambda)의 활용 - Predicate, Consumer, Function (0) | 2023.03.15 |
---|---|
[MODERN JAVA] 람다(Lambda)의 활용 - 실행 어라운드 패턴 (0) | 2023.03.08 |
[MODERN JAVA] 동작 파라미터화 - Comparator,Runnable,Callable (1) | 2023.01.25 |
[MODERN JAVA] 동작 파라미터화 - 익명 클래스(Anonymous Class) (0) | 2023.01.16 |
[MODERN JAVA] 동작 파라미터화 - 전략 디자인 패턴 ( Strategy Pattern ) (0) | 2022.10.24 |