关于java类加载顺序的问题,求解

lustboy 发布于 2019/03/09 13:51
阅读 603
收藏 5

MySQL连接为什么挂死了?别踩坑!>>>

前几天看到一个面试题,内容如下:

程序输出结果如下:

我知道一个类加载的时候,先加载静态属性和静态代码块,其次加载非静态属性和非静态代码块,最后调用构造函数。

可是如上,当一个类包含一个其本身的静态属性的时候,为什么会先加载它的非静态属性呢。

加载中
1
tcxu
tcxu

有关类信息加载 与 类实例化的背景知识:

1. 在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中。类型信息是由类加载器在类加载时从类文件中提取出来的。类(静态)变量也存储在方法区中。
2. 非静态代码块,在每次类被调用或者被实例化时就会被执行。
3. 静态的代码块,类似于静态变量,不论类被实例化多少次,该区域代码只在第一次时执行一次。

类 Demo2 的加载过程开始:
    通过 这个类的全限定名 Demo2 来获取此类的二进制字节流;
    将这个字节流所代表的静态存储结构,依代码次序,转化为方法区的运行时数据结构;
    首先,要搞定第一个 Demo2 类型的静态属性 demo;

    按操作符 new 的要求,实例化一个对象。据 2 所示,要执行非静态代码块,输出 "2", 并搞定非静态属性(成员变量) int a = 100。
    然后调用 Demo2 类的构造方法,执行此方法的第一行代码,输出 "3"。
    再执行此方法的第二行代码:
    虽然此刻已经为 静态属性 static int b 分配了空间,但它尚未被初始化赋值(200),因此,b 仍然存有缺省值 0。
最后,输出 "a=100,b=0"。

    至此,Demo2 类的构造方法调用完毕, 第一个 Demo2 类型的静态属性 demo搞定。

    接着,执行 静态代码块,输出 "2"。
    将 200 赋予静态属性 b, 以完成其初始化。
类 Demo2 的加载完毕。
最终,通过 类 Demo2 的驱动方法,调用 方法 run(), 输出 "4"。

如果将 有关 Demo2 类型的静态属性 demo 的代码移到类定义的最后一行,就可以看到依代码顺序,依次搞定的场景。

1
2
3
a=100,b=200
4
public class Demo2 {
public static void main(String args[]){
	run();
		}

//	static Demo2 demo = new Demo2();
	static {
		System.out.println("1");
	}
	{
		System.out.println("2");
	}
	public Demo2(){
		System.out.println("3");
		System.out.println("a="+a+",b="+b);
	}
	public static void run(){
		System.out.println("4");
	}
	int a = 100;
	static int b = 200;
	static Demo2 demo = new Demo2();
}


参考:
java方法区

关于java中的非静态代码块和静态代码块

java中类的加载顺序介绍(ClassLoader)
 

javaxiaoz
javaxiaoz
nb
返回顶部
顶部