我使用Java 8 lambda已有几个月的时间了,现在才发现一种行为,我不记得在Java文档或编程网站中有提及。可以在以下代码中看到:
public class CompilerGeneratedLambdaExample
{
static <A,R> R callFunction(Function<A,R> function, A arg) {
return function.apply(arg);
}
static int staticFunction_arg_int_return_int(int i) {
return i;
}
public static void main(String [] args) {
/* (A) This compiles and executes as expected - stack looks like:
*
Thread [main] (Suspended (breakpoint at line 16 in CompilerGeneratedLambdaExample))
CompilerGeneratedLambdaExample.staticFunction_arg_int_return_int(int) line: 16
1268650975.apply(Object) line: not available
CompilerGeneratedLambdaExample.callFunction(Function<A,R>, A) line: 11
CompilerGeneratedLambdaExample.main(String[]) line: 33
*/
Object value = callFunction(CompilerGeneratedLambdaExample::staticFunction_arg_int_return_int,new Integer(10));
System.out.println("value type: " + value.getClass().getName());
System.out.println("value: " + value);
/* (B) This will not compile- error message is:
*
The method callFunction(Function<A,R>, A) in the type CompilerGeneratedLambdaExample is not applicable for the arguments (IntUnaryOperator, Integer)
*/
IntUnaryOperator specializedFunction = CompilerGeneratedLambdaExample::staticFunction_arg_int_return_int; // OK
//Object value = callFunction(specializedFunction,new Integer(10)); // produces compiler error quoted above
}
}
这些评论基于我在Java 1.8遵从级别上使用最新版本的eclipse Java编译器所看到的内容。我对情况的总结是:
(A)如果将特殊类型的函数对象作为方法引用传递给需要该类型的泛型对应函数的方法,则编译器将包装处理转换参数和返回值的对象。
(B)但是,如果首先将方法引用分配给特殊类型的变量,然后尝试将该变量传递给需要通用类型的函数,则会出现指示类型不匹配的编译器错误。
行为(A)提供了对特殊功能类型的方法引用进行自动装箱和拆箱的功能,对于我正在做的工作非常有用。行为(B)如果可行,也将很有用,但事实似乎与Java对象类型系统的常规工作不符。
我的问题是–这两种行为在哪里–尤其是行为(A)在Java文档中处理了专门功能类型的方法引用提供了自动装箱和拆箱的等效功能,并且在网络上还有其他关于它们的有用讨论?
最佳答案
问题是您分配给IntUnaryOperator
,而不是Function<Integer, Object>
。你可以做
Object value2 = callFunction(
CompilerGeneratedLambdaExample::staticFunction_arg_int_return_int,
new Integer(10));
要么
Function<Integer, Object> specializedFunction =
CompilerGeneratedLambdaExample::staticFunction_arg_int_return_int;
Object value2 = callFunction(specializedFunction, new Integer(10));
或使用自动装箱
Function<Integer, Object> specializedFunction =
CompilerGeneratedLambdaExample::staticFunction_arg_int_return_int;
Object value2 = callFunction(specializedFunction, 10);
至于文档,请参见JLS-15.27. Lambda Expressions