【IT168 技术文档】
Class对象是用来创建类的常规对象的,当我们编译一个Java类就会同时产生一个与该类相对应的Class对象(保存在.class文件中)。该Class对象中保存了创建对象所需的所有信息。
共有三种产生Class对象的方法下面分别说明之:
1.public static Class Class.forName("完整的类名") throws ClassNotFoundException;
public static Class forName(String name, boolean initialize,
ClassLoader loader) throws ClassNotFoundException
假若我们用Class.forName("");的方式获取Class对象,其实就相当于Class.forName("完整类名", true, this.getClass().getClassLoader())也就是说在默认情况下在产生Class对象的同时会对该Class对象进行初始化(若以前没有初始化过)。
2.public final Class getClass()
可以通过任何实例对象来引用该方法来获取相应的Class对象。使用此种方式的前提是我们需要产生相应的实例对象。
3.类名.class 此种方式产生Class对象较前两种简单,无需第一种还要进行异常处理(在编译期就进行错误的检查了)。此种方式不会自动初始化该Class对象。初始化被延迟到对静态方法(包括构造方法)或非常数静态域进行首次引用时才进行。
import java.util.*; class Initable{ static final int staticFinal = 47; static final int staticFinal2 = ClassInitialization.rand.nextInt(100); static{ System.out.println("Initialization Initable"); } } class Initable2{ static int staticNoFinal = 147; static{ System.out.println("Initialization Initable2"); } } class Initable3{ static int staticNoFinal = 74; static{ System.out.println("Initialization Initable3"); } } public class ClassInitialization { public static Random rand = new Randdom(47); public static void main(String[] args){ Class initable = Initable.class; //不会引起初始化 System.out.println("after creating Initable reference"); System.out.println(Initable.staticFinal); //引用编译器常量不会引起初始化 System.out.println(Initable.staticFinal2); //引起初始化 System.out.println(Initable2.staticNoFinal); //引用非编译期常量会引起初始化 Class initable3 = Class.forName("Initable3"); //默认会引起初始化 System.out.println("after creating Initable3 reference"); System.out.println(Initable3.staticNoFinal);//前面已经初始化此处不用再初始化 } }
输出结果:
after creating Initable reference
47
Initialization Initable
258
Initialization Initable2
147
Initialization Initable3
after creating Initable3 reference
74
如果一个static final值是编译期常量,那么对该值的引用无需对其所在类进行初始化;若仅仅是static和final但不是编译期常量,则会引发初始化其类。若是引用一个static值则要进行链接并对其所在类进行初始化。