【问题标题】:How to use Function with primitive return or argument type in Java?如何在 Java 中使用具有原始返回或参数类型的函数?
【发布时间】:2017-08-05 17:25:14
【问题描述】:

在 Java 8 中,有一个类似于函数指针 (java.util.function.Function) 的特性。它通常像这样使用:Function<LookupKey,LookupResult>,但是,如果该方法返回原始类型,则会出现问题。 Function<ArgType,Void.TYPE> 不起作用,它无法编译并出现非常令人困惑的错误消息(“找不到符号 Void.TYPE”)。我宁愿避免更改我的方法以返回 Object 只是为了传递 null 作为结果。

【问题讨论】:

  • 错误消息只是由于您假设static 字段Void.TYPE 的存在具有任何相关性而令人困惑。由于在泛型类型签名中,允许使用类、类型变量或其他泛型类型,编译器说它没有找到该名称的 symbol,这意味着没有名为 @987654328 的类@,没有名为 Void.TYPE 的类型变量,也没有名为 Void.TYPE 的泛型类型。

标签: generics functional-programming java-8


【解决方案1】:

如果您的函数不应返回值,请考虑改用Consumer<T>

如果您的函数应该返回ìntlong,请考虑使用返回原始类型的ToIntFunction<T>ToLongFunction<T>

如果您的函数应该返回boolean,则使用Predicate<T>

最后,如果您需要使用原始类型但想要返回引用类型,请使用 IntFunction<T>LongFunction<T>

要完成列表:IntToLongFunctionLongToIntFunctionIntUnaryOperatorLongUnaryOperator 支持要使用和返回的原始类型。

【讨论】:

  • 我想知道为什么没有 IntToIntFunction。 java.util.function.Function 有一个子类型 - java.util.function.UnaryOperator。所以原始版本是java.util.function.IntUnaryOperator 接口。
  • 是的,我错过了枚举我现在添加的两个接口IntUnaryOperatorLongUnaryOperator。谢谢@VsevolodGolovanov
【解决方案2】:

改用消费者界面。不返回任何内容的过程不是“函数”。

【讨论】:

    【解决方案3】:

    正如 Harmlezz 所提到的,您应该使用 ToIntFunction<T> 或任何其他“toPrimitiveType”函数,如果您的方法没有返回值,请使用 Consumer<T>

    但为了完成 - 出于好奇,什么是可能的:

    如您所见,java 中有一个Void 类,您可以定义一个返回Void 的函数:

    Function<Long,Void> f = i -> {
            System.out.println(i);
            return ???;
        };
    

    当然你可以只返回null,但这会导致讨厌的 NullPointerExceptions,例如这不起作用

    f.apply(123L).toString();
    

    你不能创建Void 实例——除非你使用反射:)

    所以让我们创建一个 VOID 文字(假设它没有被安全设置禁止)

    static Void VOID;
    
    static {
        try {
            Constructor<Void> vc = Void.class.getDeclaredConstructor();
            vc.setAccessible(true);
            VOID = vc.newInstance();
        } catch (Exception e) {
            throw new Error(e);
        }
    }
    

    现在你只需在你的函数中返回这个字面量:

    Function<Long,Void> f = i -> {
            System.out.println(i);
            return VOID;
        };
    

    函数应用程序会产生一个非空的 Void 类型的结果

    System.out.println(f.apply(123L).getClass());
    

    打印出来:

    123
    class java.lang.Void
    

    但是,除非您想演示毫无意义的边缘情况,否则切勿在代码中使用它;)

    【讨论】:

      猜你喜欢
      • 2019-05-08
      • 1970-01-01
      • 2018-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多