类初始化
来源:互联网 发布:电脑报 淘宝二手苹果 编辑:程序博客网 时间:2024/05/22 06:13
加载阶段,java虚拟机规范中并没有进行强制约束;
但初始化阶段,虚拟机规范则严格规定了有且只有5种情况必须立即对类进行“初始化”;
1)遇到new,getstatic,putstatic 或invokestatic指令,如果类没有进行过初始化,则需要先触发初始化;
即使用new 实例化对象,读取或设置一个类的静态变量(被final修饰,已在编译期把结果放入常量池的静态字段除外)的时候,以及调用一个类的静态方法的时候。
2)使用java.lang.reflect 包的方法对类进行反射调用的时候,如果类没有进行过初始化,则需要先触发其初始化;
3)当初始化一个类的时候,如果发现父类还没有进行过初始化,则需要先触发其父类的初始化。
4)当虚拟机启动时,用户需要指定一个要执行的主类(包括 main()方法的那个类),虚拟机会先初始化这个类;
5)当使用JDK1.7 的动态语言支持时,如果一个java.lang.invoke.MethodHandle 实例最后的解析结果REF_getStatic、REF_putStatic、REF_invokeStatic的方法句柄,并且这个句柄所对应的类没有进行初始化,则需要先触发其初始化。
举几个例子说明:
public class Parent { public static String PARENT ="parent"; public static final String FINAL_PARENT = "final_parent"; static { System.out.println("parent static code"); } public Parent(){ System.out.println("parent init"); } public static String getStatic(){ return "parent static method"; }}
public class Sub extends Parent { public static String PARENT ="sub"; static { System.out.println("sub static code"); } public Sub(){ System.out.println("sub init"); }// public static String getStatic(){// return "sub static method";// }}
例子1: 没有new,不会初始化Parent 类
public class Main { public static void main(String[] args){ Parent parent; }}
结果:没有任何输出
查看Main.class,可以看出Main这个类没有Parent类的入口,说明编译的时候就会遵守虚拟机的一些规则
public class Main {
public Main() {
}
public static void main(String[] args) {
}
}
例子2: new 会引发类初始化
public class Main {
public static void main(String[] args){
Parent parent = new Parent();
}
}
结果:输出:
parent static code
parent init
查看Main.clas,有了new Parent入口
public class Main {
public Main() {
}
public static void main(String[] args) {
new Parent();
}
}
例子3: 获取static变量,会类初始化,不会调用构造函数
public class Main {
public static void main(String[] args){
System.out.println(Parent.PARENT);
}
}
输出:
parent static code
parent
对应class类
public class Main {
public Main() {
}
public static void main(String[] args) {
System.out.println(Parent.PARENT);
}
}
例子4:设置static变量,会类初始化,不会调用构造函数
public class Main {
public static void main(String[] args){
Parent.PARENT = "hello";
}
}
输出:
parent static code
例子5: 调用被final修饰,已在编译期把结果放入常量池的静态字段,不会类初始化
public class Main {
public static void main(String[] args) {
System.out.println(Parent.FINAL_PARENT);
}
}
只输出:final_parent
对应class为:
public class Main {
public Main() {
}
public static void main(String[] args) {
System.out.println("final_parent");
}
}
例子6: 调用类的静态方法,类会初始化
public class Main {
public static void main(String[] args) {
System.out.println(Parent.getStatic());
}
}
输出:
parent static code
parent static method
例子7: 通过子类调用父类的static方法,不会初始化子类
public class Main {
public static void main(String[] args) {
System.out.println(Sub.getStatic());
}
}
输出:
parent static code
parent static method
如果将Sub类中的注释部分解开;
输出:
parent static code
sub static code
sub static method
例子8: new子类,会先初始化其父类
public class Main {
public static void main(String[] args) {
new Sub();
}
}
输出:
parent static code
sub static code
parent init
sub init
阅读全文
0 0
- 类初始化
- 类初始化
- 类初始化
- 类初始化
- 类初始化
- 类初始化
- 类初始化
- 类初始化与对象初始化
- 类初始化与类对象初始化
- 类的初始化与对象的初始化
- 类的初始化和对象的初始化
- java类初始化和对象初始化
- 类的直接初始化、复制初始化、赋值
- Swift 类的初始化和反初始化
- Swift - 类初始化和反初始化方法
- Java类的初始化、变量的初始化
- 变量的初始化、类的初始化
- 接口初始化和类初始化区别
- [PAT-乙级]1062.最简分数
- 百度2017春招<度度熊买帽子问题>Java代码
- 怎么把下划线整体下移上移,让下划线和文字距离随便调整。
- FFT频谱泄露和加窗 (一)
- xsd 学习
- 类初始化
- [PAT-乙级]1063.计算谱半径
- Ubuntu(Linux)比Windows的优点(纯个人感受,无任何引用抄袭)
- 顺序表笔记
- 内部类大展身手 ———— 有抽象类的多继承
- 对最初脚本的扩展完善版本CheckAndNaming Tool
- 荷兰国旗
- POJ
- codeforces 20 c 堆优化dijkstra + 路径打印