一、JVM和Java体系结构( 七 )


构造器方法中指令按语句在源文件中出现的顺序执行 。
()不同于类的构造器 。(关联:构造器是虚拟机视角下的())
若该类具有父类,WM会保证子类的()执行前,父类的()已经执行完毕 。
虚拟机必须保证一个类的()方法在多线程下被同步加锁 。
package com.lxg.java;/*** @author shkstart* @create 2020 上午 11:23*/public class DeadThreadTest {public static void main(String[] args) {Runnable r = () -> {System.out.println(Thread.currentThread().getName() + "开始");DeadThread dead = new DeadThread();System.out.println(Thread.currentThread().getName() + "结束");};Thread t1 = new Thread(r,"线程1");Thread t2 = new Thread(r,"线程2");t1.start();t2.start();}}class DeadThread{static{if(true){System.out.println(Thread.currentThread().getName() + "初始化当前类");while(true){}}}}
只会初始化一次,并且谁抢到了就会加锁
package com.lxg.java;/*** @author shkstart* @create 2020 下午 6:01*/public class ClassInitTest {private static int num = 1;static{num = 2;number = 20;System.out.println(num);//System.out.println(number);//报错:非法的前向引用 。}private static int number = 10;//linking之prepare: number = 0 --> initial: 20 --> 10public static void main(String[] args) {System.out.println(ClassInitTest.num);//2System.out.println(ClassInitTest.number);//10}}
在类加载的过程中,首先会执行静态成员变量的初始化,包括静态变量和静态代码块 。因此,在这段代码中,int= 10;会先被执行,其值会被赋为0 。然后,静态代码块会被执行,将num的值赋为2,的值赋为20 。最后,的值又被赋为10,这是因为在类加载的阶段,被赋为默认值0,而在阶段,又被重新赋值为20,最终又被赋值为10 。因此,静态成员变量的初始化顺序是先执行静态变量的初始化,再执行静态代码块的内容 。
Java非法向前引用变量_指尖凉的博客-CSDN博客
如果字段会进行初始化,一定要防止在初始化前程序中访问默认值(可以赋值但不可访问),这会导致很多意想不到的麻烦
静态代码的执行顺序:
【一、JVM和Java体系结构】静态代码块的执行顺序是在类被加载时执行,且只会执行一次 。具体的执行顺序如下:1. 先执行父类的静态代码块,再执行子类的静态代码块 。2. 静态代码块的执行顺序与它们在类中出现的顺序有关,按照代码顺序依次执行 。3. 静态变量的初始化也是在静态代码块中进行的,因此静态变量的初始化顺序也与静态代码块的执行顺序有关 。总之,静态代码块的执行顺序是在类加载时执行,按照代码顺序依次执行,且只会执行一次 。
这里给出一个完整的例子,包括类的加载、初始化和静态变量的初始化等过程:
public class StaticBlockExample {static {System.out.println("StaticBlockExample静态代码块1");}public static int staticVar = 1;static {System.out.println("StaticBlockExample静态代码块2");}public static void main(String[] args) {System.out.println("StaticBlockExample静态变量的值为:" + staticVar);}}class ChildStaticBlockExample extends StaticBlockExample {static {System.out.println("ChildStaticBlockExample静态代码块1");}public static int childStaticVar = 2;static {System.out.println("ChildStaticBlockExample静态代码块2");}}
输出结果为:
StaticBlockExample静态代码块1StaticBlockExample静态代码块2ChildStaticBlockExample静态代码块1ChildStaticBlockExample静态代码块2StaticBlockExample静态变量的值为:1
我们可以看到,在程序运行时,首先加载类,执行它的静态代码块,输出"静态代码块1"和"静态代码块2",然后初始化静态变量的值为1 。