Java8 메서드 레퍼런스
JAVA/Java 8

Java8 메서드 레퍼런스

반응형

메서드 레퍼런스
 
-  메서드 레퍼런스는 이름과 동일하게 메서드를 대상으로  람다식의 간략형이며메서드 참조를 나타내는 예약어로서 (::) 사용한다다시 말해서 메서드 레퍼런스는  그대로 메소드를 참조해서 매개 변수의 정보  리턴 타입을 알아내어람다식에서  필요한 매개 변수를 제거하는 것이 목적이다
메소드 참조의 예와 그에 대한 람다식은 다음과 같다.

기본 구조
 String::valueOf     x  -> String.valueOf(x)
 Object::toString    x  -> x.toString()
 x::toString            () -> x.toString()
왼쪽은 메서드 레퍼런스이고 오른쪽은 람다식이다.


메서드 레퍼런스의 3가지 형태
:: 연산자는 객체 또는 클래스와 메서드 이름을 구분하며 가지의 경우로 사용된다.
1. Object::instaceMethod
text -> System.out.println(text);

2. Class::staticMethod
정적(static) 메소드를 참조할 경우에는 클래스 이름 뒤에 :: 기호를 붙이고 정적 메소드 이름을 기술하면된다.
클래스 :: 메소드
 
예를 들어  개의 값을 받아  수를 리턴하는 Math 클래스의 max() 정적 메소드를 호출하는 람다식은다음과 같다.
(left, right) -> Math.max(left, right);
 
람다식은 단순히  개의 값을 Math.max() 메소드의 매개값으로 전달하는 역할만 하기 때문에 다소 불편하다.
 
그래서 메소드 레퍼런스를 사용하여 깔끔하게 처리할  있다.
Math :: max;

3. Class::instanceMethod
인스턴스 메소드일 경우에는 먼저 객체를 생성한 다음 참조 변수 뒤에 :: 기호를 붙이고 인스턴스 메소드 이름을 기술하면 된다.

예를 들면




1
2
3
4
5
6
7
8
9
10
11
12
Class Greeter { 
    Public void greet() {
        System.out.println("Hello, world!");
    }
}
    
Class ConcurrentGreeter extends Greeter {
    Public void greet() {
        Thread t = new Thread(super::greet);
        t.start();
    }
}
cs





2,3 사용 예제
 IntBinaryOperator 인터페이스는 두 개의 int 매개값을 받아 int 값을 리턴하므로 Math :: max 메소드 참조를 대입할 수 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// static wedulObject 클래스
public class WedulObject {
    public static int staticMethod(int x, int y) {
        return x + y;
    }
    
    public int instanceMethod(int x, int y) {
        return x + y;
    }
}
 
// 테스트 메인 클래스
 
public class Java8Test {
    public static void main(String args[]) {
        IntBinaryOperator operator;
        
        // Class:staticMethod, 람다식
        operator = (x, y) -> WedulObject.staticMethod(x, y);
        System.out.println" class::staticMethod (람다) : " + operator.applyAsInt(12));
        
        // Class:staticMethod, 메서드 레퍼런스
        operator = WedulObject::staticMethod;
        System.out.println" class::staticMethod (메서드 레퍼런스) " + operator.applyAsInt(12));
        
        // Class:instanceMethod
        WedulObject object = new WedulObject();
        operator = (x, y) -> object.instanceMethod(x, y);
        System.out.println" class::instanceMethod (람다) " + operator.applyAsInt(13) );
        
        // Class::instanceMethod
        operator = object::instanceMethod;
        System.out.println" class::instanceMethod (메서드 레퍼런스) " + operator.applyAsInt(13));
    }
}
cs







매개 변수의 메소드 참조
- 메소드는 람다식 외부의 클래식 멤버일 수도 있고람다식에서 제공되는 매개변수의 멤버일 수도 있다.
- 위에서 설명한 3번째 구조인 Class::instanceMethod방식에서는  번째 파라미터가 해당 메서드의 대상이   있다.

Ex) (a, b) -> { a.instanceMethod(b);}
  이것을 메소드 참조로 표현할 경우에는 a 클래스 이름을 기술하고 :: 붙이고 메소드 이름을 적어주면 된다.


추가 예제
 식을 하단에 소개할 Method Reference 사용하면  간단하게   있다. Java8에서 새로 도입될 ::연산자를 사용하면 다음과 같이 정적 메소드나 인스턴스 메소드를 참조   있다. :: 사용하여 지정하면 함수언어에서 에타 확장이라 알려진 과정에 의해 컴파일러가 해당 메소드를 자동으로 "확장"해서Consumer 함수형 인터페이스에 있는 유일한 추상 메소드와 같은 시그니처를 만들어 주고 결과를 Consumer 인스턴스로 사용될  있게 된다.

 에타 확장 
에타 확장이란 어떤 함수 f 있을 , (x) -> f(x) f 같다는 뜻.  매개변수를 붙이면 에타확장. 매개변수를 때어내면 에타 축소라고 한다.
Ex) 에타 축소 : numbers.forEach(System.out::println);
Ex) 에타 확장 : numbers.forEach((x) -> System.out::println(x))





1
2
3
4
5
6
7
// 기존의 반복문 사용 방식
for (int i = 0; i < 10; i++) {
    System.out.println(i);
}
        
// 메소드 레퍼런스의 에타 축소 개념을 사용한 코드
IntStream.range(010).forEach(System.out::println);
cs






반응형

'JAVA > Java 8' 카테고리의 다른 글

Java8 인터페이스의 정적 메소드  (0) 2018.05.30
Java8 인터페이스 default Method (디폴트 메소드)  (0) 2018.05.30
Java8 변수 유효 범위  (0) 2018.05.30
Java8 생성자 레퍼런스  (0) 2018.05.30
Java8 기초 설명  (0) 2018.05.30