猿问

为什么超类字段的泛型类型不会被擦除到子类型的具体绑定中?

package ir.openuniverse;


public class Main {

    public static void main(String[] args) throws NoSuchFieldException {

        System.out.println(A.class.getField("t").getType().getName());

    }

}


class A extends B<D> {}

class B<T extends C> {

    public T t;

}


class C {}

class D extends C {}

输出为ir.openuniverse.C。为什么?我希望D!


繁星淼淼
浏览 121回答 3
3回答

慕田峪9158850

编译期间,Java的类型擦除更改class B<T extends C> {public T t;}至 :class B<C> {public C t;}由于getType()标识了字段的声明类型,因此输出为ir.openuniverse.C

弑天下

谢谢大家的帮助。最后,我被迫将A的定义更改为:class A extends B<D> {&nbsp; &nbsp; public D t;}就我的目的而言已经足够了(尽管我一点都不喜欢它!)。编辑:超越方式不是基本方式。请参阅下面的@DanielPryden的前两个注释。替代解决方法:class A extends B<D> {&nbsp; &nbsp; @Override public D getT() { return super.getT(); }}class B<T extends C> {&nbsp; &nbsp; private T t;&nbsp; &nbsp; public T getT() { return t; }}并在main():System.out.println(A.class.getMethod("getT").getReturnType().getName());输出: ir.openuniverse.D另一种方式:注意:这不是解决主要问题的方法(请参阅下面的@DanielPryden的第四条评论)。但是也许可以帮助您(像我一样)。当您至少有以下一个实例时,可以使用此解决方法A:public class Main {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; A a = new A();&nbsp; &nbsp; &nbsp; &nbsp; System.out.println(a.t.getClass().getName());&nbsp; &nbsp; &nbsp; &nbsp; // Or via reflection:&nbsp; &nbsp; &nbsp; &nbsp; // System.out.println(a.getClass().getField("t").get(a).getClass().getName());&nbsp; &nbsp; }}class A extends B<D> {&nbsp; &nbsp; { t = new D(); }}class B<T extends C> {&nbsp; &nbsp; public T t;}输出: ir.openuniverse.D
随时随地看视频慕课网APP

相关分类

Java
我要回答