我正在使用来自第三方库(Reflections)的方法,该方法应该找到给定类型的子类型,看起来像
public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type) {
...
当来电者代码看起来像
时Class<?> type = ...
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
我收到编译错误:“cannot convert from Set<Class<? extends capture#19-of ?>> to Set<Class<?>>
”。以下内容解决了这种情况:
Class<?> type = ...
Set<?> subTypes = reflections.getSubTypesOf(ht);
因此看起来错误的Set<Class<? extends ?>>
唯一可能的补救方法是Set<?>
,而不是Set<Class<?>>
。为什么会这样?
谢谢你对此有任何解释。
答案 0 :(得分:8)
请改用以下内容:
Set<? extends Class<?>> subTypes = reflections.getSubTypesOf(type);
问题是嵌套通配符不执行type capture。声明Set<Class<?>>
表示“一组任何类型的”,而返回的是Set<Class<? extends capture#19-of ?>>
,这意味着“一组任何类型的类扩展自< em>某些特定的未知类型“。在这种情况下,“特定未知类型”派生自T
的类型参数,该参数从type
推断为无限通配符捕获(?
Class<?>
})。
例如,假装“特定未知类型”为Number
:
Class<Number> type = ...
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
此处,getSubTypesOf
返回Set<Class<? extends Number>>
。该类型不可分配给Set<Class<?>>
,因为generic types aren't covariant。但是,通配符捕获有助于我们表达协方差,允许类似Set<? extends Class<?>>
之类的类型。需要注意的是,除了null
之外,我们不能添加任何内容,因为我们不知道它的具体类型。
相关帖子:
类似帖子:
答案 1 :(得分:1)
由于?
是通配符,当您插入Class<?>
时,该方法返回Set<Class<? extends ?>>
(纯粹是理论上的,Java不支持) - 尝试使用具体类型调用该方法(例如Class<Number>
),您应该返回Set<Class<? extends Number>>
。
答案 2 :(得分:1)
以下内容会有所帮助:您的? extends T
右侧Class
(受T限制)getSubTypesOf
将其退回),因此您需要在左侧扩展它:
Class<? extends T> type;
Set<Class<? extends T>> subTypesOf = getSubTypesOf(type);
而不是:
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
答案 3 :(得分:1)
你必须考虑'?'意思是'未知',而不是'任何'。
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
子类型是一组“未知”类。它可以是String,Integer,List ......中的任何一个。
getSubTypesOf(type)将返回一组但未知的类。我使用'确定',因为我们知道所有人都会扩展类型。所以它不一样。问题是你似乎不知道编译时的类型类。
Set<Class>
也应该有效,但它会显示警告,因为你没有将通用与Class一起使用。