2017-01-09 41 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返回类型。