2017-01-09 31 views
0

我遇到一個Java項目下面的代碼,我不知道該用它來做什麼:功能接口的對象強制

public Function<CustomEnum,String> foo(SomeObject someObject) { 
    return ((Function<CustomEnum,String>) (someObject::toString)).andThen(r -> someObject::getSomethingWithEnumParameter); 
} 

我真的不明白,你怎麼能投的東西一個功能界面。那有什麼意思?

返回值的結果類型不是任何值someObject。

是不是Function<CustomEnum, String>定義了一個匿名函數,採用類型CustomEnum並返回String

我已經閱讀了關於Function<T,R>的java文檔,說實話,這比我讀文檔之前沒什麼意義。

這是我相信正在發生的事情。

  1. FOO返回了適用於一些CustomEnum一個匿名函數返回一個字符串

  2. FOO的內部匿名函數(這是某種投射到someObject::toString,我不明白)是應用於將從foo(someObject).apply(customEnum)的初始呼叫傳遞的CustomEnum

  3. andThen將從foo中的匿名函數(這是鑄造某種程度上,我仍然不明白)的結果字符串,然後返回值someObject::getSomethingWithEnumParameter。爲什麼不是返回類型只是someObject::getSomethingWithEnumParameter的類型,爲了討論的緣故,我們會說它是Map<R,T>

如果有人能幫助我理解這個流程,我將不勝感激。

+0

該代碼很討厭,如果該開發者在我的團隊中,我會和他/她進行認真的談話。完成該操作的正確方法是創建一個單獨的方法,其主體是'return someObject.getSomethingWithEnumParam(someObject.toString());',因此可以將該方法的簡單引用用作函數。 – VGR

回答

2

在一個理想的世界中,這將工作:

public Function<CustomEnum,String> foo(SomeObject someObject) { 
    return (someObject::toString).andThen(...); 
} 

但是,Java爲了含蓄創建方法引用的接口實例都需要一個接口類型,因此顯式轉換需要轉換爲功能。接口類型。

一旦你有一個函數的實例,那麼你可以按照正常的方式調用它的任何方法,在這種情況下,這個方法使用另一個函數對象來組成它,以形成一個新函數。

其分解:

someObject::toString是隱含類型Function<CustomEnum, String>的方法參考。即toStringSomeObject中的一種方法,它採用CustomEnum類型的參數並返回String

r -> someObject::getSomethingWithEnumParameter雖然有錯誤的類型 - 它是一個返回函數的函數。如果你擺脫了「r ->」部分,那麼它是有效的,只要someObject::getSomethingWithEnumParameterSomeObject上的方法,其需要String並返回String。或者,退貨類型foo需要更改爲Function<CustomEnum, Function<String, String>>

如果合併這兩個與andThen那麼你有一個Function這需要一個CustomEnum並返回一個String,公關的foo返回類型。