2014-04-17 25 views
6

我對「引用特定類型的任意對象的實例方法」背後的概念感到困惑。甲骨文documentation大約有這樣一個例子:使用方法引用而不是多參數lambda

String[] stringArray = { "Barbara", "James", "Mary", "John", "Patricia", "Robert", "Michael", "Linda" }; 
Arrays.sort(stringArray, String::compareToIgnoreCase); 

多數時候我已經看到了這種方法的參考例子是這樣的:如果拉姆達是這樣的:x -> x.func(),那麼你可以把它寫像ClassOfX::func。在文檔中的示例表示:

的方法參考 字符串等效lambda表達式::與compareToIgnoreCase將有正式的參數列表 (字符串一個,串B),其中,a和b是用於更好地任意名稱 描述了這個例子。方法引用將調用方法 a.compareToIgnoreCase(b)。

的問題是:對於任何兩個參數的lambda像(a, b) -> a.func(b)func方法必須是實例的第一個參數和λ的第二個參數的方法將作爲一個參數傳遞給該方法通過?如果我們有多個參數lambda那麼func方法必須是lambda的第一個參數的實例方法,lambda的其他參數將按照出現在lambda中的順序傳遞給func?我的意思是代替(a, b, c) -> a.func(b, c)我們可以寫ClassOfA::func

對不起我的英文。我希望我明確地解決了這個問題。

回答

11

SomeClass::func可能意味着兩件事,具體取決於func是靜態方法還是實例方法。

(1)如func是一個靜態方法,然後SomeClass::func是,僅僅通過了所有的參數的方法的λ:

(a, b, c) -> SomeClass.func(a, b, c); 

(2)如func是一個實例方法,然後SomeClass::func是一個拉姆達使用第一個參數爲實例,你想:

(a, b, c) -> a.func(b, c); 

其中a具有類型SomeClass

編輯:索蒂里奧斯扎的回答表明又一不同的類型的方法的參考:example::method其中example是參考變量(而不是一個類名稱)。這意味着相同

(a, b) -> example.method(a, b); 

或者更準確

(a, b) -> __someFinalTemporary.method(a, b); 

其中__someFinalTemporary被分配給example在其中,該方法參考被評爲點,因此,如果example變化後,該方法仍然是稱爲使用較早的值example

[第四種是SomeClass::new,它將參數傳遞給構造函數。我認爲這就是他們全部。]

+1

+1爲徹底。 –

3

我的意思,而不是(A,B,C) - > a.func(B,C),我們可以寫ClassOfA :: FUNC

是的,這是正確的。

7

下面是一個演示實例方法參考行爲的小示例。

public class Example { 
    public static void main(String[] args) throws Exception { 
     List<String> strings = new ArrayList<String>(); 
     Example example = new Example(); 
     Functional methodRef = example::method; 
     methodRef.funct("a string", strings); 
     System.out.println("List now contains: " + strings); 

     Functional lambda = (String s, List<String> l) -> { 
      example.method(s, l); 
     }; 
     lambda.funct("another string", strings); 
     System.out.println("List now contains: " + strings); 
    } 

    interface Functional { 
     void funct(String value, List<String> list); 
    } 

    void method(String value, List<String> toAddTo) { 
     System.out.println("adding"); 
     toAddTo.add(value); 
    } 
} 

它打印

adding 
List now contains: [a string] 
adding 
List now contains: [a string, another string] 

兩個或多或少等價物。在lambda的情況下,該方法調用的變量需要實際上是final

相關問題