注意,有一点很有意思,当使用“.class”来创建对Class对象的引用时,不会自动地初始化该Class对象。
为了使用类而做的准备工作实际包含三个步骤:
1.加载
。这是由类加载器执行的。该步骤将查找字节码,并从这些字节码中创建一个Class对象。
2.链接
。这个阶段将验证类中的字节码,为静态域分配存储空间,并且如果必需的话,将解析这个类创建的对其他类的所有引用。
3.初始化
。如果该类具有超类,则对其进行初始化,执行静态初始化器和静态初始化块。
初始化被延迟到对静态方法(构造器隐式地是静态的)或者非常数静态域进行首次引用时才执行:
import java.util.*;
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");
// Does not trigger initialization:
System.out.println(Initable.staticFinal);
// Does trigger initialization:
System.out.println(Initable.staticFinal2);
// Does trigger initialization:
System.out.println(Initable2.staticNonFinal);
Class initable3 = Class.forName("Initable3");
System.out.println("After creating Initable3 ref");
System.out.println(Initable3.staticNonFinal);
}
}
/* Output:
After creating Initable ref
47
Initializing Initable
258
Initializing Initable2
147
Initializing Initable3
After creating Initable3 ref
74
*///:~
1.从initable引用的创建中可以看到,仅使用.class语法来获得对类的引用不会引发初始化。
2.Class.forName()的方法立即进行了初始化,如initable3的引用的创建。
3.如果一个static final值是“编译期常量”,就像Initable.staticFinal,那么这个值不需要对Initable类进行初始化就可以被读取。
4.如果只是将一个域设置为static final,还不足以确保这种行为,例如,对Initable.staticFinal2的访问将强制进行类的初始化,因为它不是一个编译期常量。
5.如果一个static域不是final的,那么对它访问时,总是要求在它被读取之前,要先进行链接(为这个域分配存储空间)和初始化(初始化该存储空间 ),就像对Initable2.staticNonFinal的访问所看到的那样。
分享到:
相关推荐
java类中静态域、块,非静态域、块,构造函数的初始化顺序,通过本例子,能够清楚了解到java类的初始化顺序
通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
Java 的初始化问题和...《Thinking in java》把这种“需要”概括为创建第一个对象时或首次访问静态域或静态方法 时。Sun 公司说类初始化的时机是“initialize on first actice use”, (在首次主动使用时初始 化)。
○2在Student类建立构造方法初始化各域的值,并统计学生人数count; ○3创建分别获得各域(学号,姓名,性别和年龄)的public方法,以及分别设置各域(学号,姓名,性别和年龄)值的public方法(即get、set方法);...
第一部分:声明、初始化、和作用域。 定义类、内部类、静态类、接口、枚举。 正确使用包语句和导入语句,包括静态导入。 实现或继承一个或多个接口。 定义、继承抽象类。声明、初始化并使用基本类型、...
静态成员不是某对象私有的(所有对象共有,修改一个对象的静态成员,其他所有的都修改,同时这也是RTTI的原理),他要求在声明时初始化(不能在类作用域内初始化),并且, 这个成员也不计算在calss的大小里面(你...
静态变量只存在于函数作用域内,静态变量只存活在栈中。一般的函数内变量在函数结束后会释放,比如局部变量,但是静态变量却不会。... //这里定义并初始化一个静态变量 $nums public static $nums=0; func
所以,静态数据成员的定义(初始化)不应该被放在头文件中。 其定义方式与全局变量相同。举例如下: xxx.h文件 class base{ private: static const int _i;//声明,标准c++支持有序类型在类体中初始化,但vc6不支持...
类的初始化 成员初始化 构造器初始化初始化顺序 数组初始化 对象的销毁 对象作用域 this 和 super 访问控制权限继承 多态组合代理 向上转型static final 接口和抽象类接口 抽象类异常 认 识 Exception 什么是 ...
(1)用于对静态字段、只读字段等的初始化。 (2)添加static关键字,不能添加访问修饰符,因为静态构造函数都是私有的。 (3)类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的...
5.7.3. 显式的静态初始化 5.7.4. 非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 第7章 复用类 第8章 多态 第9章 接口 第10章 内部类 第11章 持有对象 第12章 通过...
非静态实例初始化 5.8 数组初始化 5.8.1 可变参数列表 5.9 枚举类型 5.10 总结 第6章 访问权限控制 第7章 复用类 第8章 多态 第9章 接口 第10章 内部类 第11章 持有对象 第12章 通过异常处理错误 第13章 字符串 第...
6)静态类的初始化方法中,对于FLASH插件的载入采用了第三方资源:SWFObject类提供的方法,可根据浏览器的不同而进行不同的装载方式。在Wormhole.js脚本文件中,有大部分代码是SWFObject 1.5版源码压缩后的COPY.感谢...
(1)加在局部变量的前面使之成为静态局部变量,作用域还是在函数内部,可是生存周期延长了。 (2)加在全局变量的前面限定该变量作用域为文件作用域,就是说即使其他文件使用了extern扩展作用域也不行。这在C语言的...
7.3 静态域与静态方法 7.3.1 静态域 7.3.2 静态方法 7.3.3 Math类 7.4 构造方法 7.4.1 默认的域初始化 7.4.2 默认构造方法 7.4.3 拷贝构造方法 7.4.4 重载构造方法 7.4.5 调用构造方法 7.4.6 初始化块 ...
3.15 作为方法名来初始化对象 50 3.16 作为参数传递 51 3.17 Java方法重载 52 3.18 Java类的基本运行顺序 53 3.19 Java包装类、拆箱和装箱详解 54 3.20 包装类的应用 54 3.20.1.1 1) 实现 int 和 Integer 的相互转换...
15.4.3 匿名内部类的初始化 337 15.4.4 匿名内部类作用的体现 337 15.5 理解内部类 339 15.6 内部接口 340 15.6.1 定义在类中的内部接口 340 15.6.2 定义在接口中的内部接口 341 15.7 小结 342 第16...
当执行一个类的静态初始化程序的过程中,发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。 java.lang.IllegalAccessError 违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用...