package RTTI; public class SweetShop { public static void main(String[] args) { System.out.println("inside main"); new Candy(); System.out.println("After creating Candy"); try { Class.forName("RTTI.Gum"); }catch (ClassNotFoundException e){ System.out.println(e); } System.out.println("After Class.forName(\"Gum\")"); new CooKie(); System.out.println("After creating Cookie"); } } class Candy{ static { System.out.println("Loading Candy"); } } class CooKie{ static { System.out.println("Loading Cookie"); } } class Gum { static { System.out.println("Loading Gum"); } }
static子句,static初始化是在类加载时进行的。
Class.forName();取得Class对象的引用的一种方法,它是用一个包含目标类的文本名的String作输入参数,返回一个Class对象的引用。如果类还没有被加载就加载它。在传递给forNam()的字符串中,你必须使用权限定名(包含包名)
Class对象使用getName()来产生全限定的类名,并分别使用getSimpleName()和getCanonicalName()来产生不含包名的类名和全限定的类名。isInterface()方法如同其名,可以告诉你这个Class对象是否表示某个接口。因此,通过Class对象,你可以发现你想要了解的类型的所有信息。
在main()中调用的Class.getInterfaces()方法返回的是Class对象,它们表示在感兴趣的Class对象中所包含的接口。
如果你有一个Class对象,还可以使用getSuperclass()方法查询其直接基类,这将返回你可以用来进一步查询的Class对象。因此,你可以在运行时发现一个对象完整的类继承结构。
Class的newInstance()方法是实现“虚拟构造器”的一种途径,虚拟构造器允许你声明:“我不知道你的确切类型,但是无论如何要正确地创建你自己。”在前面的示例中,up仅仅是一个Class引用,在编译期不具备任何更近一步的类型信息,当你创建新实例时,会得到Object引用,但是这个引用指向的是Toy对象。当然,在你可以发送Object能够接收的消息之外的任何消息之前,你必须更多地了解它,并执行某种转型。另外,使用newInstance()来创建的类,必须带有默认的构造器。
package RTTI; interface HasBatteries{} interface Waterproof{} interface Shoots{} class Toy{ Toy(){} Toy(int i){} } class FancyToy extends Toy implements HasBatteries,Waterproof,Shoots{ FancyToy(){super(1);} } public class ToyTest { static void printInfo(Class cc){ System.out.println("Class name:"+cc.getName()+" is interface?["+cc.isInterface()+"]"); System.out.println("Simple name: "+cc.getSimpleName()); System.out.println("Canonical name: "+cc.getCanonicalName()); } public static void main(String[] args) { Class c=null; try{ c=Class.forName("RTTI.FancyToy"); }catch (ClassNotFoundException e){ System.out.println("Can't find FancyToy"); System.exit(1); } printInfo(c); for(Class face:c.getInterfaces()) printInfo(face); Class up=c.getSuperclass(); Object obj=null; try{ obj=up.newInstance(); }catch (InstantiationException e){ System.out.println("Cannot instantiate"); System.exit(1); }catch (IllegalAccessException e){ System.out.println("Cannot access"); System.exit(1); } printInfo(obj.getClass()); } }
在ToyTest.java中,将Toy的默认构造器注释掉,并解释发生的现象