带有Java泛型的双通配符参数化(嵌套通配符)

Pav*_* S. 6 java generics

我正在使用来自第三方库(Reflection)的方法,该方法应该找到给定类型的子类型并且看起来像

public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type) {
...
Run Code Online (Sandbox Code Playgroud)

当调用者代码看起来像

Class<?> type = ...
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
Run Code Online (Sandbox Code Playgroud)

我收到编译错误:" cannot convert from Set<Class<? extends capture#19-of ?>> to Set<Class<?>>".以下修复了这种情况:

Class<?> type = ...
Set<?> subTypes = reflections.getSubTypesOf(ht);
Run Code Online (Sandbox Code Playgroud)

所以看起来不正确的唯一可能的补救措施Set<Class<? extends ?>>Set<?>,但不是Set<Class<?>>.为什么会这样?谢谢你对此有任何解释.

Pau*_*ora 9

请改用以下内容:

Set<? extends Class<?>> subTypes = reflections.getSubTypesOf(type);
Run Code Online (Sandbox Code Playgroud)

问题是嵌套通配符不执行类型捕获.声明一个Set<Class<?>>意味着"一组任何类型的类 ",而返回的是一个Set<Class<? extends capture#19-of ?>>,意思是"从一些特定的未知类型扩展的任何类型的一组类".在这种情况下,"特定的未知类型"是从类型参数派生的T,它被推断type为无界通配符捕获(?in Class<?>).

例如,假装"特定的未知类型"是Number:

Class<Number> type = ...
Set<Class<?>> subTypes = reflections.getSubTypesOf(type);
Run Code Online (Sandbox Code Playgroud)

在这里,getSubTypesOf返回一个Set<Class<? extends Number>>.该类型不可分配,Set<Class<?>>因为泛型类型不是协变的.但是,通配符捕获有助于我们表达协方差,允许类似的类型Set<? extends Class<?>>.需要注意的是,我们不能添加任何东西,只能添加null到这样的集合,因为我们不知道它的具体类型.

相关文章:

类似帖子:


归档时间:

查看次数:

1050 次

最近记录:

8 年,1 月 前