2017-08-16 56 views
27

當在Java中使用地圖功能我可以做到以下幾點:如何在靜態導入中使用方法引用?

import com.example.MyClass; 

someStream.map(MyClass::myStaticMethod) 

但在我的項目中,我們有時會使用靜態導入,我怎麼可以參考myStaticMethod當進口是靜態的?

我認爲這會工作,但它並不:

import static com.example.MyClass.myStaticMethod; 

someStream.map(myStaticMethod); //does not compile 

爲什麼這個不行?我是用第一個例子「卡住」的還是有其他解決方案。

回答

29

讓我們來看看Java語言規範15.13. Method Reference Expressions的相關部分。

它列出了以下的方法來創建一個方法引用:

MethodReference: 
    ExpressionName :: [TypeArguments] Identifier 
    ReferenceType :: [TypeArguments] Identifier 
    Primary :: [TypeArguments] Identifier 
    super :: [TypeArguments] Identifier 
    TypeName . super :: [TypeArguments] Identifier 
    ClassType :: [TypeArguments] new 
    ArrayType :: new 

注意,所有的人包括::令牌。

由於someStream.map(myStaticMethod)的參數不包括::,因此它不是有效的方法參考。

這表明你確實需要進口MyClass(也許除了的靜態導入,如果這是你的偏好),並參考方法MyClass::myStaticMethod

+1

通過引用JLS思考問題的好方法!但是map也可以處理其他參數,比如lambda也沒有::。是否有更抽象的類型來表示地圖將作爲參數接受的內容?哪一個會 – Xeli

3

靜態導入方法不會影響您定義方法引用的方式。

所以,如果你想要的工作,它應該長得一模一樣,就像引入靜態導入前:

MyClass::myStaticMethod 
-2

隨着你只能調用一個方法的靜態導入,但不是指它。對於stream()。map()它需要對函數的引用,以便可以爲每個條目調用它。

4

那麼它不會編譯,因爲JLS這樣說。但是這不能編譯,因爲它將是一個簡單的方法調用而不是方法參考 - 它只是使用::表示法定義的,不管它是一個靜態的或在其上使用的實例。

這仍然是一個有趣的方面,你不能解決的一個 - 可能在目前。沒有語言支持來定義類似的東西:

MethodRef <Class, Method> ref = ... 

然後以您希望的方式使用它。但我甚至不認爲這是可能的,因爲你也必須以某種方式定義參數類型和返回類型,因爲需要它來查看它是否與多個其他地方相匹配。像Predicate<String>Function<String, Boolean>這可能適用於相同的method reference

相關問題