Java API中这么解释Class类:
为了理解RTTI在Java例如何工作,首先必须了解类型信息在运行期间是如何表示的。只要用到一个名为'Class'的特殊形式的对象,这个对象包含了与类有关的信息(有时候也把它叫作“元类”)。事实上,要用Class类创建属于某个类的全部“常规”或“普通”对象。 任何一个作为程序一部分的类,都有一个Class对象。换言之,每次写一个新类时,同时也会创建一个Class对象(更恰当的说,是保存在一个完全同名的.class文件中)。在运行期间,一旦程序员想要生成某一个类的对象,用于执行程序的Java虚拟机(JVM)首先就会检查该类型的Class对象是否已经载入。若尚未载入,JVM就会查找同名的.class文件,并将其载入。所以,Java程序启动时并不是完全载入的,这一点与许多传统语言不同。一旦该类型的Class对象进入内存,就用它创建该类型的所有对象。 三、Class动态加载类的三种方法 (1)类名.Class (2)类型.getClass() (3)Class.forName('类名') (这里的类名表示具体类名,所以要加上包名) 补充: 静态加载类和动态加载类: 编译时刻加载的类是静态加载类,例如用new关键字创建的对象要通过编译器的静态检查,如果编译时该类不存在,那么使用该对象的类也无法通过编译。 运行时刻加载的类是动态类,在编译的时候不会进行判断,只有在运行时才会进行判断,假设该类不存在,在运行时才会报错。 例如下面的例子: Candy.java文件 package com.test;
public class Candy {
static{
System.out.println('Loading Candy in static block');
}
public static void main(String[] args){
System.out.println('Loading Candy in main method');
}
}
LoadClass.java文件: 运行结果如下:
Before loding Candy 从程序的输出结果来看,用这种方式和new 来创建对象没什么区别。其实,二者之间有很大的区别,用new 关键字创建对象要通过编译器静态检查,如果编译时Candy类不存在,那么使用Candy类对象的类LoadClass也无法通过编译。而forName()方法时动态加载,即便编译时Candy类不存在,编译也是可以通过的,只是在运行时刻会抛出异常。 注意:使用forName()方法存在一个问题,它返回的是一个Class类型,而不是加载的那个类型。所以,无法做出下面的声明: Candy candy=Class.forName('com.test.Candy'); 也就是说,candy无法直接使用Candy类中定义的方法。解决的办法是利用反射机制,不过这比直接用new来创建对象要麻烦得多。所以,用forName()加载对象多用在加载驱动程序的情况下(例如,加载数据库驱动)
下面举个例子熟悉一下Class动态加载类的方法: package com.baseType;
public class baseClass {
public static void main(String[] args){
Class c1=int.class; //int的类类型
Class c2=String.class; //String类的类类型
Class c3=double.class; //double的类类型
Class c4=Double.class; //Double类的类类型
Class c5=void.class; //关键字void的类类型
//打印类类型的具体名称
System.out.println(c1.getName()); //int
System.out.println(c2.getName()); //java.lang.String
System.out.println(c3.getName()); //double
System.out.println(c4.getName()); //java.lang.Double
System.out.println(c5.getName()); //void
//不带包名的类名称
System.out.println(c2.getSimpleName()); //String
System.out.println(c4.getSimpleName()); //Double
}
} |
|