分配给更通用类型的引用

时间:2018-02-05 19:35:53

标签: java generics lambda java-8

有没有办法可以使用更通用的类型来引用这个::方法?

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&lt;的映射器调用的适配器。数字&gt;

2 个答案:

答案 0 :(得分:2)

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

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

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

参见PECS,代表Producer Extends,Consumer Super。另请参阅covariance and contravariance以深入介绍此主题。

答案 1 :(得分:2)

如果您将定义更改为:

PanResponder

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

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

但是有一个像Function<Integer, Number> moreGenericRef2 = this::method; 这样的定义(其中? extends Integer是最后一个类是没有意义的)