2016-03-10 110 views
5

我想在我的代碼中使用Java 8方法引用。有四種可用的方法參考。Java 8:方法參考綁定接收器和UnBound接收器之間的區別

  1. 靜態方法參考。
  2. 實例方法(綁定接收器)。
  3. 實例方法(UnBound receiver)。
  4. 構造函數的參考。

隨着Static method referenceConstructor reference我沒有問題,但Instance Method (Bound receiver)Instance Method (UnBound receiver)真的搞糊塗了。在Bound接收機中,我們使用一個對象引用變量調用的方法等:

objectRef::Instance Method 

UnBound接收機我們使用類名來調用的方法等:

ClassName::Instance Method. 

我有以下問題:

  1. 實例方法需要不同類型的方法引用嗎?
  2. BoundUnbound接收方法參考有什麼區別?
  3. 我們應該在哪裏使用Bound接收器,我們應該在哪裏使用Unbound接收器?

我還發現BoundUnbound接收機的解釋從Java 8 language features books,但仍與實際的概念混淆。

回答

7

未結合的接收機如String::length的想法是,你指的是 方法到將作爲拉姆達的參數中的一個被提供的對象。例如, 可將lambda表達式(String s) -> s.toUpperCase()重寫爲String::toUpperCase

但有界是指當您調用 拉姆達至外部對象已存在的方法。例如,lambda表達式() -> expensiveTransaction.getValue()可以重寫爲expensiveTransaction::getValue

情況爲參考方法三種不同的方式

(args) -> ClassName.staticMethod(args) 可以ClassName::staticMethod

(arg0, rest) -> arg0.instanceMethod(rest) 可以ClassName::instanceMethodarg0ClassName類型)

(args) -> expr.instanceMethod(args) 可以expr::instanceMethod

回答Java 8 in Action book

6

基本上未綁定的接收器允許您使用實例方法,如果他們與聲明類型的第一個參數的靜態方法 - 因此你可以通過在你想要的任何實例中使用的功能。對於綁定的接收器,「目標」實例實際上是該函數的一部分。

一個例子可以說明清楚:

import java.util.function.*; 

public class Test { 

    private final String name; 

    public Test(String name) { 
     this.name = name; 
    } 

    public static void main(String[] args) { 
     Test t1 = new Test("t1"); 
     Test t2 = new Test("t2"); 

     Supplier<String> supplier = t2::method; 
     Function<Test, String> function = Test::method; 

     // No need to say which instance to call it on - 
     // the supplier is bound to t2    
     System.out.println(supplier.get()); 

     // The function is unbound, so you need to specify 
     // which instance to call it on 
     System.out.println(function.apply(t1)); 
     System.out.println(function.apply(t2)); 
    } 

    public String method() { 
     return name; 
    } 
} 
+0

一個小的查詢。你已經寫道:供應商 supplier = t2 :: method;並提供評論如下://供應商綁定到t1。這是錯字錯誤還是我不正確理解? –

+1

@Ravindrababu:只是一個錯字。現在修復... –

2

當你想爲某個類的特定實例要執行的方法,您可以使用綁定接收。

例如:

Stream.of("x","y").forEach(System.out::println); 

將上PrintStream一個sepcific實例執行println - 的System.out實例。因此將System.out.println("x")System.out.println("y")作爲將該方法引用傳遞給forEach的結果來執行。

在另一方面,如果你想爲一個類的實例未指定要執行的方法,可以使用未綁定的接收器。

例如:

Stream.of("x","y","").filter(String::isEmpty); 

將執行在每個流的String實例isEmpty() - 即"x".isEmpty()"y".isEmpty()"".isEmpty()