为什么泛型参数上的通配符需要显式转换?

Roh*_*bhu 7 java

我有一个功能:

<T> T get(Class<T> fetchType) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

所以,如果我做的事情如下:

String x = get(String.class);
Run Code Online (Sandbox Code Playgroud)

这一切都很好.

但是,在另一个功能:

<R> R otherFunction(R base) {
    return get(base.getClass());
}
Run Code Online (Sandbox Code Playgroud)

给我一个错误,因为base.getClass()回报? extends R.

reason: no instance(s) of type variable(s) exist so that capture of ? extends Object conforms to R
inference variable T has incompatible bounds:
equality constraints: capture of ? extends Object upper bounds: Object, R
Run Code Online (Sandbox Code Playgroud)

现在从我的理解,函数get(Class<T> x)返回T,所以当调用时? extends R,可以说是CAP#1,但从get现在返回CAP#1,将其分配给类型R应该不是问题.为了测试这个,我试过:

Class<? extends CharSequence> stringClass = String.class;
CharSequence x = get(stringClass);
Run Code Online (Sandbox Code Playgroud)

这似乎没有任何问题.出了什么问题?

编辑:这是因为类型擦除,在运行时没有R可用的信息,但是CharSequence?哪个仍然没有意义,因为仅仅在编译阶段这不是纯粹的检查?

因此,事实证明,Object.getClass()返回Class<? extends |X|>而不是Class<? extends X>,其中|X|擦除的X原因在于它适用于具体类型(例如? extends CharSequence,但不适用于泛型类型).IntelliJ可能没有准确报告,这引起了混乱:http://i.imgur.com/yE8LswM.jpg (我尝试拍摄截图,但弹出窗口一直在消失).

And*_*ner 6

原因在Javadoc中描述Object.getClass:

public final Class<?> getClass()
Run Code Online (Sandbox Code Playgroud)

实际结果的类型是Class<? extends |X|>其中|X|是静态类型上其表达的擦除getClass被调用.

所以,当你调用base.getClass(),实际的结果是Class<?>,由于擦除RObject.事实并非如此Class<? extends R>.

  • @RohanPrabhu我会说这是intellij中的一个错误. (2认同)