Class对象就是用来创建类的所有的“常规”对象的。每一个类都对应了一个Class对象(被保存在一个.class文件里)。
所有的类都是在对其第一次使用时,动态加载到JVM中的。一旦一个类的Class对象被载入内存,它就被用来创建这个类的所有对象。
获取Class对象的方式有两种
一:Class.forName("包名.类名");
二:类名.class;(类字面常量)
第二种方式更简单,安全(编译时就会收到检查),因为不用调用forName方法,所以更高效。
当使用第二种方法来创建Class对象的引用时,不会自动地初始化该Class对象。
看下面代码:
package com.test;
import java.util.Random;
public class Candy {
public static Random rand = new Random(47);
public static final int num1 = 1;
public static final int num2 = rand.nextInt(1000);
static {
System.out.println("loading candy");
}
public static void staticMethod(){
System.out.println("-------staticMethod--------");
}
}
package com.test;
public class Test {
public static void main(String args[]) {
/****** Class.forName() ********/
// try {
// Class c1 = Class.forName("com.test.Candy");
// System.out.println("get Class by Class.forName()");
// } catch (ClassNotFoundException e) {
// e.printStackTrace();
// }
/****Candy.class****/
Class c2 = Candy.class;
System.out.println("get Class by Candy.Class");
System.out.println("num--->"+Candy.num1);
System.out.println("---------------------");
// System.out.println("random num ---->"+Candy.num2);
System.out.println("num is not final --->"+Candy.num3);
}
}
当执行第一种方法时,输出信息如下
loading candy
get Class by Class.forName()
可以看出在获取Class对象的时候,就进行了初始化。
当采用第二种方法时,输入信息如下
get Class by Candy.Class
num--->1
---------------------
loading candy
random num ---->258
初始化被延迟了,当调用静态方法(构造器隐式的是静态的)或首次引用非常数静态域(不是编译期常量)或引用一个非final的静态域时才会进行初始化。