我有一个接受通配符列表的方法,但也接受java.util.function.Function
的实现,该实现接受列表包含的相同类型的元素并返回String
。要做到这一点,我有两个想法,但它们都不令人满意。
方法1:使方法通用。
public <T> void method(List<T> list, Function<T, String> function){
...
}
方法2:让Function
的第一个类型成为通配符?
public void method(List<?> list, Function<?, String> function){
...
}
我不喜欢方法1,我甚至不确定方法2是否有效,因为有时我会得到如下的奇怪错误:
error: incompatible types: Object cannot be converted to CAP#1
where CAP#1 is a fresh type-variable:
CAP#1 extends Object from capture of ?
我是否有另一种方法可以在不离开Function
参数原始的情况下创建这样的方法?
答案 0 :(得分:4)
使用方法的 wildcast 版本
public void method(List<?> list, Function<?, String> function)
是不可能的,因为 - 正如您已经注意到的那样 - 不可能使用Wildcast作为变量的类型。
不使用泛型类型参数还有另外一种方法。你可以尝试使用
public void method(List<Object> list, Function<Object, String> function)
作为方法的签名,如果你真的想要使用包含多个类的实例的列表list
。
但是,如果你只想允许一种类型的元素,你肯定必须使用泛型,所以你的方法必须看起来像你已经在你的问题中显示的那样:
public <T> void method(List<T> list, Function<T, String> function)
如果你的问题是如何调用你的方法,以防你使用泛型,那很简单。说,你有List<Integer> list
。如果您再调用method(list,...)
,则list
的泛型类型会自动确定function
的第一个类型参数,在这种情况下,function
必须是{{1}的实例}}。因为你想使用lambda表达式来调用方法,比如
Function<Integer, String>
完全正确。
答案 1 :(得分:0)
这是一个疯狂的猜测,但我认为问题在于:
public void method(List<?> list, Function<?, String> function){
...
}
您可能假设签名中的两张外卡都属于同一类型。尝试这样的事情:
public <T> void method(List<T> list, Function<T, String> function){
...
}