我有以下代码:

class SuperClass {
    public static String getName() { return "super"; }
}

class SubClass extends SuperClass {
    public static String getName() { return "sub"; }
}

public class Dummy<T extends SuperClass> {
    public void print() {
        System.out.println("SuperClass: " + SuperClass.getName());
        System.out.println("SubClass: " + SubClass.getName());
        System.out.println("T: " + T.getName());
    }
    public static void main(String[] args) {
        new Dummy<SubClass>().print();
    }
}

此代码输出如下所示:

SuperClass: super
SubClass: sub
T: super

我的问题是: 为什么不T.getName()返回)SubClass.getName的值(?毕竟,我指定是t ==子类。或者是通用引用静态函数调用无效?

感谢在前进!

有帮助吗?

解决方案

这不只是泛型的问题。

如果你说:

SuperClass obj = new SubClass();
System.out.println(obj.getName());

您还将获得“超级”。有没有“多态”的静态方法。

在你的情况下,所有的编译器知道T是它扩展SuperClass,所以它会调用SuperClass.getName()

其他提示

和C ++不同模板,Java泛型通过类型擦除工作,所以只产生用于T的所有值中的一个类,并且将所有的参考文献在此类键入T到超类型T的,在这种情况下SuperClass,然后使用虚拟调度提供方差调用对象的方法,和静态派遣调用静态方法。

所以,当你做Dummy<SubClass>.print(),编译器不与在T SubClass Dummy的全局替换。所有的编译器是检查T的使用作为Dummy的方法的参数或返回类型是SubClass。还有里面Dummy任何代码没有变化,所以同样SuperClass静态方法被调用任何T是。

如果要在这取决于参数化类型的通用类不同的行为,必须通过在该类型的一个对象,并使用虚拟方法,或通过在类类型和使用反射。

当你实例化与“新的虚拟()”之类的你叫实际上不设置任何默认构造函数。 当打印方法得到了调用,VM看到T的类型,如类声明中声明,是父类;然后它调用这个类的静态方法。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top