BackEnd/Java

[Java] 메소드 레퍼런스란?

꾹꾹이 2022. 10. 9.
728x90

메소드 레퍼런스란?

 

람다식에서 불필요한 매개변수를 제거하여 사용할 수 있게 해주는 것

 

즉, 람다 표현식을 더 간력하게 만드는 표현방법이라고 할 수 있다.

메소드 레퍼런스를 이해하기 위해선 람다식을 이해해야 한다. 람다식 이해에 관한 글은 아래 링크에서 확인할 수 있다.

https://grandma-coding.tistory.com/entry/Java-함수형-인터페이스란

 

[Java] 함수형 인터페이스란?

함수형 인터페이스란? 추상 메서드를 하나만 갖는 인터페이스 @FuncationInterface 어노테이션을 갖는 인터페이스 Single Abstract Method(SAM) 인터페이스 예시 1 2 3 public interface FunctionalInterface {..

grandma-coding.tistory.com

 

메소드 레퍼런스를 사용할 때는 ::를 사용한다.

단순한 예제를 통해 이해해보자.

1
2
3
4
5
6
7
8
9
10
11
Consumer<String> func = text -> System.out.println(text);            //람다 표현식
Consumer<String> func = System.out::println;                        //메소드 레퍼런스
 
Function<String, Integer> lengthStr1 = string -> string.length();    //람다 표현식
Function<String, Integer> lengthStr2 = String::length;                //메소드 레퍼런스
 
BiFunction<StringString, Boolean> equalCheck1 = (str1, str2) -> str1.equals(str2);    //람다 표현식
BiFunction<StringString, Boolean> equalCheck2 = Object::equals;                        //메소드 레퍼런스
 
BinaryOperator<Integer> maxNum1 = (num1, num2) -> Math.max(num1, num2);    //람다 표현식
BinaryOperator<Integer> maxNum2 = Math::max;                            //메소드 레퍼런스
cs

 

괄호를 생략할 수 있고, ClassName::MethodName 형식으로 사용한다.

 

메소드를 참조하는 방법

  1. 스태틱 메소드 참조(클래스::static 메소드)
  2. 특정 객체의 인스턴스 메소드 참조(객체::인스턴스 메소드)
  3. 임의의 객체의 인스턴스 메소드 참조(클래스::인스턴스 메소드)
  4. 생성자 참조(클래스::new)

 

1. 스태틱 메소드 레퍼런스

아래와 같은 함수형 인터페이스가 존재한다.

1
2
3
4
@FunctionalInterface
public interface IAdd {
  int add(int x, int y);
}
cs

 

그리고 두 매개변수를 더한 값을 반환하는 메소드가 있다.

1
2
3
4
5
public class MathUtils {
  public static int AddElement(int x, int y) {
    return x + y;
  }
}
cs

 

아래 코드는 람다식과 메소드 레퍼런스를 사용한 예제이다.

1
2
3
4
5
6
7
8
9
10
11
public class Main {
  public static void main(String args[]) {
    System.out.println("Lambda Expression");
    IAdd addLambda = (x, y) -> MathUtils.AddElement(x, y);
    System.out.println(addLambda.add(1020));
 
    System.out.println("Method Reference");
    IAdd addMethodRef = MathUtils::AddElement;
    System.out.println(addMethodRef.add(2040));
  }
}
cs

 

 

2. 특정 객체의 인스턴스 메소드 참조

MathUtiils 클래스의 메소드를 비정적 메소드(non-static)로 변경한다. 

1
2
3
4
5
public class MathUtils {
  public int AddElement(int x, int y) {
    return x + y;
  }
}
cs

 

아래 코드는 특정 객체의 인스턴스를 메소드로 호출하는 예제이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Main {
  public static void main(String args[]) {
    // MathUtils 클래스의 객체를 생성합니다.
    MathUtils mu = new MathUtils();
        
    // 객체로 메서드를 호출하는 람다식입니다.    
    System.out.println("Lambda Expression");
    IAdd addLambda = (x, y) -> mu.AddElement(x, y);
    System.out.println(addLambda.add(1020));
 
    // 객체로 메서드를 호출하는 메서드 참조입니다.
    System.out.println("Method Reference");
    IAdd addMethodRef = mu::AddElement;
    System.out.println(addMethodRef.add(2040));
  }
}
cs

 

위 예제는 객체를 생성하지 않고 람다식 또는 메소드 참조에서 인스턴스화 할 수도 있다.

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {
  public static void main(String args[]) {
  
    System.out.println("Lambda Expression");
    IAdd addLambda = (x, y) -> new MathUtils().AddElement(x, y);
    System.out.println(addLambda.add(1020));
 
    System.out.println("Method Reference");
    IAdd addMethodRef = new MathUtils()::AddElement;
    System.out.println(addMethodRef.add(2040));
  }
}
cs

 

3. 임의의 객체의 인스턴스 메소드 참조

1
2
3
4
String[] names = {"vvv","ahreum","hong"};
Arrays.sort(names, String::compareToIgnoreCase)//Comparator 함수형 인터페이스
 
System.out.println(Arrays.toString(names)); // ahreum, hong, vvv
cs

 

4. 생성자 참조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class A_MethodReference {
    private String name;
 
   //입력값 없는 생성자 (case 1)
    public A_MethodReference(){
    }
   //입력값 받는 생성자 (case 2)
    public A_MethodReference(String name){
        this.name = name;
    }
}
 
//입력값 없는 생성자 만들어짐 (case 1)
Supplier<A_MethodReference> a_methodReference= A_MethodReference::new;
a_methodReference.get(); // 이 때 만들어짐
 
//입력값 받는 생성자 만들어짐 (case 2)
Function<String, A_MethodReference> ahriGreeting = A_MethodReference::new;
A_MethodReference aMethodReference2 = ahriGreeting.apply("ahreum");
System.out.println(aMethodReference2.getName()); // ahreum
cs

댓글