【问题标题】:Assign to a reference of a more generic type分配给更通用类型的引用
【发布时间】:2018-02-05 19:35:52
【问题描述】:

有什么方法可以使用如下更通用的类型来引用 this::method?

Number method(Integer input){ return 1;}

void test(){
    Function<Integer, Number> ref = this::method; //OK
    Function<Number, Number> moreGenericRef = this::method // does not compile.
    Function<? extends Number, Number> moreGenericRef2 = this::method // does not compile.
}

我希望能够做到以下几点。

Map<String, Function<Number,Number>> maps;
maps.add("method1", this::method)
maps.add("method2", this::method2)

maps.get("methods1").apply(1.2);
maps.get("methods2").apply(1);

函数是适配器,会被Stream的mapper调用

【问题讨论】:

  • 没有。您不能将任何 Number 传递给期望 Integer 的方法。
  • 真正的错误是你认为你需要这个。您可能想描述您的实际需求,而不是向我们展示XY Problem
  • @dwong:没错,这就是它应该的样子。如果您“需要访问 Integer.class 中的方法”,那么您实际上并没有拥有 Function&lt;Number, Number&gt;,而且再多的恶作剧也不会改变这一点。 Java 编译器在这里做的是正确的事情。
  • 只出现在方法内部没关系。这与 lambdas 无关,真的。您不能通过将任意数字传递给方法来实现采用任意数字的方法。

标签: java generics lambda java-8


【解决方案1】:

你需要函数的参数是逆变而不是协变

Function<? super Integer, ? extends Number> moreGenericRef2 = this::method;

这编译得很好,并且还允许返回类型是Number 的任何后代。

请参阅PECS,它代表 Producer Extends、Consumer Super。有关该主题的深入介绍,另请参阅 covariance and contravariance

【讨论】:

  • 感谢您的回答;但是,它不会编译 incompatible types: invalid method reference Function&lt;? super Number, ? extends Number&gt; moreGenericRef2 = this::method; ^ incompatible types: Number cannot be converted to Integer
  • 是的,但不清楚 OP 是否有这样的方法或试图分配它。
【解决方案2】:

如果您将定义更改为:

Function<? extends Integer, ? extends Number> moreGenericRef2 = this::method;

Function<Integer, ? extends Number> moreGenericRef2 = this::method;

Function<Integer, Number> moreGenericRef2 = this::method;

但是有一个诸如? extends Integer 之类的定义(其中Integer 是一个最终类无论如何都没有意义)

【讨论】:

  • Function&lt;? extends Integer, 是一个无用的定义。也可以使用Function&lt;?,
  • @tsolakp 它会编译,但它(几乎)没用,就像我说的那样。
  • @shmosel。它甚至不会编译。
  • @tsolakp 嗯,你是对的,但这似乎是类型推断的失败。这有效,例如:Function&lt;?, Number&gt; ref = (Function&lt;Integer, Number&gt;)this::method;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
  • 2023-03-12
  • 1970-01-01
相关资源
最近更新 更多