//: typeinfo/toys/GenericToyTest.java
// Testing class Class.
package typeinfo.toys;
public class GenericToyTest {
public static void main(String[] args) throws Exception {
Class<FancyToy> ftClass = FancyToy.class;
// Produces exact type:
FancyToy fancyToy = ftClass.newInstance();
Class<? super FancyToy> up = ftClass.getSuperclass();
// This won’t compile:
// Class<Toy> up2 = ftClass.getSuperclass();
// Only produces Object:
Object obj = up.newInstance();
}
} ///:~
If you get the superclass, the compiler will only allow you to say that the superclass reference is "some class that is a superclass of FancyToy " as seen in the expression Class <? super FancyToy >. It will not accept a declaration of Class<Toy> . This seems a bit strange because getSuperclass( ) returns the base class (not interface) and the compiler knows what that class is at compile time—in this case, Toy.class , not just "some superclass of FancyToy." In any event, because of the vagueness, the return value of up.newlnstance( ) is not a precise type, but just an Object.作者好像还是没有解释为什么程序中Class<Toy> up2 = ftClass.getSuperclass();这个不能编译通过的原因,好像是她自己也解释不好。请问是这样吗?该如何理解上述程序以及作者的阐述呢?麻烦大神们给予小弟一点指示~Java
// Testing class Class.
package typeinfo.toys;
public class GenericToyTest {
public static void main(String[] args) throws Exception {
Class<FancyToy> ftClass = FancyToy.class;
// Produces exact type:
FancyToy fancyToy = ftClass.newInstance();
Class<? super FancyToy> up = ftClass.getSuperclass();
// This won’t compile:
// Class<Toy> up2 = ftClass.getSuperclass();
// Only produces Object:
Object obj = up.newInstance();
}
} ///:~
If you get the superclass, the compiler will only allow you to say that the superclass reference is "some class that is a superclass of FancyToy " as seen in the expression Class <? super FancyToy >. It will not accept a declaration of Class<Toy> . This seems a bit strange because getSuperclass( ) returns the base class (not interface) and the compiler knows what that class is at compile time—in this case, Toy.class , not just "some superclass of FancyToy." In any event, because of the vagueness, the return value of up.newlnstance( ) is not a precise type, but just an Object.作者好像还是没有解释为什么程序中Class<Toy> up2 = ftClass.getSuperclass();这个不能编译通过的原因,好像是她自己也解释不好。请问是这样吗?该如何理解上述程序以及作者的阐述呢?麻烦大神们给予小弟一点指示~Java
不过我也做出了一点点探索:
这段代码要结合前面的一段“typeinfo/toys/ToyTest.java”以及泛型在Class中的运用来理解。带有泛型的class在有明确类型的情况下,newInstance返回的同样是明确类型的实例:
Class<FancyToy> ftClass = FancyToy.class;
FancyToy fancyToy = ftClass.newInstance;
但是在遇到获取直接基类的情况下,却不能使用明确的泛型定义,只能是个范围声明:
Class<? super FancyToy> up = ftClass.getSuperclass();
?表示不确定,那这个class的类型既然不确定,执行newInstance返回的也是不确定类型的对象,只能用Object类型的引用:
Object obj = up.newInstance();
类似这样的显示定义是编译不了的:
Class<Toy> up2 = ftClass.getSuperclass();
但是可以强制转换:
Class<Toy> up2 = (Class<Toy>) ftClass.getSuperclass();
这种转换是安全的,不会报错。起初我怀疑这么设计是因为编译器不知道ftClass的父类到底是谁,但java只是单继承,所以我怀疑可能是基于对父类的父类的考虑,但通过调试可得出结论:getSuperclass仅仅获取的是直接父类的class,因此证明了作者的结论:编译器其实是知道其父类类型的!但就是要保留这样一种模糊的声明方式,是为了日后扩展支持多继承吗?