class对象
1.Java程序在它开始运行之前并非完全加载,而是等到各个部分在必需时才加载的,也就是说当你第一次创建一个对象时或第一次对类的静态成员引用,或者第一次调用相关方法时,它就加载,而后面的多次这样重复操作,它是不会再次加载的。
2.JVM为使用类而做的三个准备步骤:
- 加载:这是由类加载器执行的,该步骤将查找字节码(通常在classpath所指定的路径中查找,但如果找不到,会在当前路径查找),并从这些字节码中创建一个Class对象。
- 链接:在链接阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
- 初始化:如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块。
3.Class.forName()和类名.class的主要区别:Class.forName()加载类的同时,也会初始化该类,而类名.class是可以在编译期受到检查,并且它加载类,而不初始化类。对类静态常量域和静态非常量域首次引用的区别:静态常量域的首次引用不会初始化类,而静态非常量域首次引用会初始化类。
代码例子:
class Initable {
static final int staticFinal = 47;
static final int staticFinal2 =
ClassInitialization.rand.nextInt(1000);
static {
System.out.println("Initializing Initable");
}
}
class Initable2 {
static int staticNonFinal = 147;
static {
System.out.println("Initializing Initable2");
}
}
class Initable3 {
static int staticNonFinal = 74;
static {
System.out.println("Initializing Initable3");
}
}
public class ClassInitialization {
public static Random rand = new Random(47);
public static void main(String[] args) throws Exception {
//不会初始化该类
Class initable = Initable.class;
System.out.println("After creating Initable ref");
//不会初始化该类
System.out.println(Initable.staticFinal);
// 会初始化该类
System.out.println(Initable.staticFinal2);
// 会初始化该类
System.out.println(Initable2.staticNonFinal);
//会初始化该类
Class initable3 = Class.forName("beyondboy.Initable3");
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNonFinal);
}
}
输出结果:
After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3 ref
74