메소드 참조 Method References
메소드 참조는 메소드를 간결하게 지칭할 수 있는 방법으로 람다가 쓰이는 곳 어디서나 사용할 수 있습니다. '참조’라는 말에서 알 수 있듯이 이미 존재하는 이름을 가진 메소드를 람다로써 사용할 수 있도록 참조하는(가리키는) 역할을 합니다.
즉, 일반 함수를 람다 형태로 사용할 수 있도록 해줍니다. 그리고 메소드를 호출(실행)하는 것이 아니라 참조만 하기 때문에, 이름 뒤에 소괄호는 쓰지 않습니다.
우리가 메소드 참조로 작성하면 컴파일러는 메소드를 참조를 보고 람다를 생성합니다. 사용법은 다음과 같습니다.
1 | // 원래 함수 |
메소드 참초를 이용해 동일한 형식의 람다를 해당 인터페이스에 할당할 수 있습니다.
1 | interface Example { |
다양한 메소드 참조를 살펴보겠습니다.
- 기본 사용법
- 생성자 참조
- 스태틱 메소드 참조
- 인스턴스 메소드 참조 (1)
- 인스턴스 메소드 참조 (2)
기본
기본적인 사용법입니다.
1 | // 람다로 사용하기 위한 함수형 인터페이스 작성 |
생성자 참조
실제로 생성자를 호출해서 인스턴스를 생성하는 것이 아니라 생성자 메소드를 참조하는 것 뿐입니다.
1 | String::new |
예제를 살펴보겠습니다.
1 | // Factory 는 임의의 객체를 반환하는 create 메소드를 가진 함수형 인터페이스 |
제네릭 타입을 추가해도 잘 동작합니다.
1 | public void usage () { |
인자를 받는 생성자의 경우를 생각해보겠습니다. 컴파일러가 함수형 인터페이스를 통해 어떤 생성자를 사용할 지 판단합니다.
1 | // Person 클래스와 여러 인자를 받는 생성자 |
스태틱 메소드 참조
메소드 참조는 스태틱 메소드를 직접적으로 가리킬 수 있습니다.
1 | String::valueOf |
예제를 살펴보겠습니다.
1 | public static class Comparators { |
인스턴스 메소드 참조 (1)
특정 인스턴스의 메소드를 참조할 수 있습니다. 클래스 이름이 아닌 인스턴스명을 적어주면 됩니다.
1 | x::toString // x 는 접근하고자 하는 인스턴스 |
이러한 방법은 이미 정의되어 있는 메소드를 (함수형 인터페이스가 맞다면) 람다로 재사용할 수 있게 해줍니다. 함수형 인터페이스 간의 전환도 가능합니다.
1 | Callable<String> c = () -> "Hello"; // 함수형 메소드는 call |
좀 더 자세한 예제를 살펴보겠습니다.
1 | public void example () { |
인스턴스 메소드 참조 (2)
앞에서 살펴 본 내용에 따르면 다음 메소드 참조에서 Obejct
는 클래스를 의미할 것입니다. 하지만 여기서 toString
메소드는 스태틱 메소드가 아니라 일반적인 인스턴스 메소드입니다.
1 | Object::toString |
어떤 점이 다른걸까요?
1 | () -> x.toString() // 클로저라서 알고 있었다 |
헷갈릴 수 있는데 좀 더 자세히 살펴보겠습니다.
1 | public void lambdaExample() { |
내부적으로는 인스턴스 메소드 참조 (1)은 클로저이고, (2)는 람다입니다. (1)은 미리 알 수 있는 특정 객체의 인스턴스 메소드이고, (2)는 나중에 전달받는 임의의 객체의 인스턴스라고 볼 수 있습니다.
요약
이번 포스팅에서 살펴본 메소드 참조를 정리해보겠습니다.[1]
1 | // 생성자 참조 |