Java_34_메소드 레퍼런스(Method Reference)

OngTK·2025년 9월 30일

Java

목록 보기
34/35

Java 메소드 레퍼런스(Method Reference) 정리


1. 개요

  • 형태: 대상 :: 메소드명 또는 클래스명 :: new(생성자), 타입[] :: new(배열 생성자)
  • 람다식과 동일한 의미를 더 간결히 작성하는 문법 설탕(syntactic sugar). 실제로는 람다와 같이 invokedynamic을 통해 SAM 구현이 생성됨.
  • 중요: 정적 메소드만 가능한 것이 아님. 정적/인스턴스/생성자/배열 생성자 모두 가능.
  • 사용 전제: 참조하려는 메소드 시그니처가 대상 함수형 인터페이스의 단일 추상 메소드(SAM) 시그니처와 호환되어야 함.

2. 종류와 형태

분류형태의미예시
정적 메소드 참조ClassName::staticMethod클래스의 정적 메소드를 참조Function<String,Integer> f = Integer::parseInt;
특정 객체의 인스턴스 메소드 참조 (bound)instance::method이미 가진 객체의 메소드를 참조Consumer<String> c = System.out::println;
특정 타입의 임의 객체 인스턴스 메소드 참조 (unbound)ClassName::instanceMethod첫 번째 매개변수가 수신 객체가 됨BiPredicate<String,String> p = String::equals;
생성자 참조ClassName::new생성자를 참조하여 새 객체 생성Supplier<ArrayList<String>> s = ArrayList::new;
배열 생성자 참조Type[]::newN 크기의 배열 생성자 참조IntFunction<String[]> a = String[]::new;

unbound 형태 예: Function<String,Integer> f = String::length;s -> s.length() 와 동일.


3. 예시 코드로 이해하기

3.1 정적 메소드 참조

System.out.println(Integer.parseInt("123"));

Function<String, Integer> func = Integer::parseInt; // s -> Integer.parseInt(s)
System.out.println(func.apply("1234"));

3.2 인스턴스 메소드 참조

List<String> names = List.of("배두훈","강형호","조민규","배두훈");

// 람다
names.stream().forEach(name -> System.out.println(name));

// 메소드 레퍼런스 (bound: System.out 라는 특정 인스턴스의 println)
names.stream().forEach(System.out::println);

3.3 생성자 참조

// 람다
names.stream().forEach(name -> new Member(name));

// 생성자 참조
names.stream().forEach(Member::new);

// 객체 리스트로 만들기
List<Member> members = names.stream()
                            .map(Member::new)
                            .collect(Collectors.toList());
System.out.println(members);

보조 클래스:

class Member {
    String name;
    Member(String name){ this.name = name; }
}

4. 람다 → 메소드 레퍼런스 매핑 예

람다식메소드 레퍼런스
s -> Integer.parseInt(s)Integer::parseInt
x -> System.out.println(x)System.out::println
(a,b) -> a.equals(b)String::equals
() -> new ArrayList<>()ArrayList::new
n -> new Member(n)Member::new
len -> new String[len]String[]::new

5. 오버로드/제네릭과 타입 추론

  • 오버로드 주의: 동일한 이름의 메소드가 여러 개일 때, 대상 SAM의 시그니처로 하나로 귀결되어야 함. 불분명하면 형변환(cast) 로 명시.
// 예: String::valueOf는 여러 오버로드가 있으므로 필요 시 캐스팅
Function<Integer,String> f = (Function<Integer,String>) String::valueOf;
  • 제네릭: 컴파일러가 타입을 추론하지만, 복잡한 체이닝에서는 타입 인자를 명시하거나 중간 변수로 분리하면 오류를 줄일 수 있음.

6. Stream과 함께 쓰는 빈출 패턴

  • 출력: list.forEach(System.out::println)
  • 변환: map(String::trim), map(Object::toString)
  • 정렬 키추출: sorted(Comparator.comparing(String::length))
  • 수집기 생성자: collect(Collectors.toCollection(ArrayList::new))
  • 맵 수집: collect(Collectors.toMap(User::id, User::name, (a,b)->a, LinkedHashMap::new))
  • 비교자: Comparator<String> cmp = String::compareToIgnoreCase;sorted(cmp)

7. 함수형 인터페이스와 시그니처 호환 표

인터페이스SAM 시그니처가능한 예시 메소드 참조
Supplier<R>R get()ArrayList::new, Locale::getDefault
Consumer<T>void accept(T)System.out::println, Logger::info
Function<T,R>R apply(T)Integer::parseInt, String::trim
BiFunction<T,U,R>R apply(T,U)Math::max, String::replace
Predicate<T>boolean test(T)Objects::isNull, String::isEmpty
BiPredicate<T,U>boolean test(T,U)String::equals, Pattern::matches
UnaryOperator<T>T apply(T)String::toLowerCase
BinaryOperator<T>T apply(T,T)BigInteger::add

8. this/super 메소드 레퍼런스 (심화)

  • this::instanceMethod : 현재 인스턴스의 메소드 참조
  • super::instanceMethod : 상위 타입의 메소드 참조 (내부/익명 클래스 등에서 유용)
class Base { void greet() { System.out.println("base"); } }
class Child extends Base {
    void greet() { System.out.println("child"); }
    void run() {
        Runnable r1 = this::greet;  // child
        Runnable r2 = super::greet; // base
        r1.run(); r2.run();
    }
}

9. 제약과 주의사항

  • 부분 적용(partial application) 불가: 필요한 매개변수를 일부만 채워둘 수 없음.
  • 체크 예외: 참조 메소드가 체크 예외를 던지면, 대상 인터페이스가 그 예외를 던질 수 있어야 함.
  • 부작용 최소화: 메소드 레퍼런스 자체는 간결하지만, 참조 대상 메소드가 부작용을 가지면 Stream 파이프라인의 예측 가능성이 떨어짐.
  • 가독성 우선: 모든 람다를 메소드 레퍼런스로 바꿔야 하는 것은 아님. 의미가 더 명확할 때에만 사용.

10. 요약

  • 메소드 레퍼런스는 람다식을 더 간단하게 표현하는 문법.
  • 정적/인스턴스/생성자/배열 생성자 참조를 지원.
  • 핵심은 함수형 인터페이스의 시그니처와의 호환. 모호하면 형변환으로 명시.
  • Stream과 함께 사용할 때 코드 가독성과 재사용성이 향상.
profile
2025.05.~K디지털_풀스택 수업 수강중

0개의 댓글