java - 寻求有关编译器生成的 lambda 表达式的文档,以将 Java 8 中的专用函数对象转换为通用函数对象

标签 java lambda autoboxing functional-interface unboxing

我已经使用 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

关于java - 寻求有关编译器生成的 lambda 表达式的文档,以将 Java 8 中的专用函数对象转换为通用函数对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57565518/

相关文章:

java - 如何对 AJAX 应用程序进行黑盒测试?

c# - 错误的重载导致编译器错误

java - 自动装箱 - 这两行之间的区别?

java - 为什么 int num = Integer.getInteger ("123") 会抛出 NullPointerException?

java - 在 Java 中从 JMenuBarbar 访问 JMenuItems?

java - Parse.com 如何将 ParseUser 添加到当前用户的好友列表

java - young GC 暂停与 STW 暂停

python - Python可以 pickle lambda函数吗?

eslint 或 jslint 中的 Javascript lambda/匿名函数长度警告

java - 数字提升和平等?