메서드 참조란?
이미 정의된 메서드를 그대로 참조하여 람다 표현식을 더 간결하게 작성하는 문법이다.
즉, 람다가 단순히 이미 정의된 어떤 메서드를 호출하는 경우, 이를 축약해준다.
람다와 관련된 포스팅은 해당 글을 참고하면 좋을 것 같다.
람다 -> 메서드 참조
Function<String, Integer> function = s -> s.length();
매개변수로 문자열이 들어오면 문자열의 길이를 반환해주는 람다식이다.
Function<String, Integer> function = String::length;
위 람다식을 변환한 메서드 참조 형태이다.
'::' 연산자를 사용해 메서드 참조를 나타 낼 수 있다.
메서드 참조에서는 컴파일러가 시그니처(매개변수, 타입)을 바탕으로 메서드 참조와 연결해주기 때문에, 명시적으로 매개변수를 작성하지 않아도 자동으로 추론되어 호출된다.
메서드 참조의 4가지 종류
람다식에서 메서드 참조는 4가지로 볼 수 있으며, 어떤 종류의 메서드를 호출하는지에 따라 달라진다.
예시로 사용될 Person 클래스이다.
public class Person {
private String name;
// == 생성자 ==
public Person() {
this("Unknown");
}
public Person(String name) {
this.name = name;
}
// == 정적 메서드 ==
public static String greeting() {
return "Hello";
}
public static String greetingWithName(String name) {
return "Hello " + name;
}
// == 인스턴스 메서드 ==
public String introduce() {
return "I am " + name;
}
public String introduceWithNumber(int number) {
return "I am " + name + ", my number is " + number;
}
}
1. 정적 메서드 참조
public class MethodRef {
public static void main(String[] args) {
// 매개변수 X
Supplier<String> staticMethod1 = () -> Person.greeting();
Supplier<String> staticMethod2 = Person::greeting;
// 매개변수 O
Function<String, String> staticMethod1 = name -> Person.greetingWithName(name);
Function<String, String> staticMethod2 = Person::greetingWithName;
}
}
인스턴스를 생성하지 않아도 접근할 수 있는 정적 메서드 참조 시 형태는 클래스::메서드이다.
2. 특정 객체 인스턴스 메서드 참조
public class MethodRef {
public static void main(String[] args) {
Person person = new Person("Kim");
// 매개변수 X
// 선언 시점부터 객체의 메서드를 호출할지 알고 있음
Supplier<String> instanceMethod1 = () -> person.introduce();
Supplier<String> instanceMethod2 = person::introduce;
// 매개변수 O
// 선언 시점부터 이미 어떤 객체의 메서드를 호출할지 알고 있음
Function<Integer, String> instanceMethod1 = n -> person.introduceWithNumber(n);
Function<Integer, String> instanceMethod2 = person::introduceWithNumber;
}
}
생성된 인스턴스의 메서드 참조 시 형태는 인스턴스::메서드이다.
3. 생성자 참조
public class MethodRef {
public static void main(String[] args) {
// 매개변수 X
Supplier<Person> newPerson1 = () -> new Person();
Supplier<Person> newPerson2 = Person::new;
// 매개변수 O
Function<String, Person> newPerson1 = name -> new Person(name);
Function<String, Person> newPerson2 = Person::new;
}
}
생성자를 통해 인스턴스를 생성할 때의 형태는 클래스::new 이다.
4. 특정 타입의 임의 객체 인스턴스 메서드 참조
1~3까지 경우는 어떤 인스턴스의 어떤 메서드가 호출될 지 컴파일러가 알고 있는 상황이였다.
하지만 이 경우는 다르다. 어떤 인스턴스가 들어올지 컴파일러는 알지 못한다. 예시로 알아보자
public class MethodRef {
public static void main(String[] args) {
Person person1 = new Person("Kim");
Person person2 = new Person("Park");
Person person3 = new Person("Lee");
// 선언 시점에 어떤 객체의 메서드를 호출할지 모름
// 실행 시점에 어떤 객체의 메서드를 호출할지 알게 됨
Function<Person, String> fun1 = (Person person) -> person.introduce();
Function<Person, String> fun2 = Person::introduce;
}
}
람다식을 보면, 매개변수로 들어오는 타입은 정해져있지만 생성된 인스턴스가 전달되는 것은 아니다.
헤당 람다식에는 타입만 일치한다면 어떤 인스턴스라도 실행시킬 수 있는 것이다.
이러한 경우의 메서드 참조 형태는 클래스::인스턴스메서드 이다
마무리
정리는 해보았지만, 이정도로 실전에서 사용하기에는 익숙하지 않을 수도 있겠다. ide에 힘을 빌려서 조금씩 익숙해져나가자
'Language > Java' 카테고리의 다른 글
| [Java] ReentrantLock을 통한 스레드 동기화 (0) | 2026.01.02 |
|---|---|
| [Java] 자바 스레드 생명 주기와 메모리 가시성 (0) | 2025.12.30 |
| [Java] Stream Collector, Downstream Collector (0) | 2025.12.26 |
| [Java] Stream API와 지연 연산 (0) | 2025.12.25 |
| [Java] 람다와 함수형 프로그래밍 (0) | 2025.12.23 |