Sha*_*per 16 java function-composition java-8
我正在研究功能组合并有一个例子:
Function<String, String> test = (s) -> s.concat("foo");
String str = test.andThen(String::toUpperCase).apply("bar");
Run Code Online (Sandbox Code Playgroud)
该示例按预期编译并运行。但是,如果我使用 更改组合的顺序compose()
,则需要显式转换:
String str = test.compose((Function <String, String>)
String::toUpperCase).apply("bar");
Run Code Online (Sandbox Code Playgroud)
如果没有显式转换String::toUpperCase
为Function <String, String>
,则会出现编译器错误:
Error:
incompatible types: cannot infer type-variable(s) V
(argument mismatch; invalid method reference
incompatible types: java.lang.Object cannot be converted to java.util.Locale)
String s = test.compose(String::toUpperCase).apply("bar");
^-------------------------------^
Run Code Online (Sandbox Code Playgroud)
问题是为什么compose()
需要显式强制转换,而andThen()
在这种情况下不需要?
正如错误消息所示,问题在于有toUpperCase
一个接受 aLocale
作为参数的重载,因此编译器错误是由于不知道String::toUpperCase
应该引用哪个重载而引起的。原则上,编译器应该能够知道带有两个参数(String
对象本身是第一个参数)的方法引用不能是 a Function
,但我认为没有这样的规则 - 或者更确切地说,没有'在泛型类型参数的推断过程中,这似乎是一个规则,这就是显式强制转换解决问题的原因。
String::trim
我们可以通过尝试不同的方法引用(例如没有重载的 )来确认重载确实是导致问题的原因:
// works without an explicit cast
String str = test.compose(String::trim).apply("bar");
Run Code Online (Sandbox Code Playgroud)
所以现在的问题是为什么在使用andThen
. 不同之处在于,andThen
以相反的顺序组合两个函数,因此需要推断的类型参数是 的输出类型String::toUpperCase
,无论String
选择哪种重载。因此,编译器似乎有一个规则来处理类型参数推断期间重载的歧义,当方法引用的返回类型将用于推断时,并且重载具有相同的返回类型。请注意,对于具有相同参数类型的重载,不能存在类似的规则,因为重载不能具有相同的参数类型。
归档时间: |
|
查看次数: |
793 次 |
最近记录: |