实践探索JAVA初始化过程

13 篇文章 1 订阅

1.JAVA在初始化的时候首先初始化静态代码块(只执行一次),然后非静态代码块,然后构造方法。

2.在各个代码块中顺序执行。

3.在存在继承关系的时候顺序为:父类static -> 子类static -> 父类非static  ->  父类构造方法 -> 子类非static ->子类构造方法。

无继承,无层次:

public class A {
	static {
		System.out.println("a-static1");
		System.out.println("a-static2");
	}
	{
		System.out.println("a-not-static1");
		System.out.println("a-not-static2");
	}
	public A() {
		System.out.println("A构造方法1");
		System.out.println("A构造方法2");
	}

        public static void main(String[] args) {
		A a = new A();
	}
}
}

执行结果:

a-static1
a-static2
a-not-static1
a-not-static2
A构造方法1
A构造方法2

与设想一样,静态非静态然后构造函数,各代码块顺序执行。

有继承,无层次:

public class A {
	static {
		System.out.println("a-static1");
		System.out.println("a-static2");
	}
	{
		System.out.println("a-not-static1");
		System.out.println("a-not-static2");
	}
	public A() {
		System.out.println("A无参构造方法1");
		System.out.println("A无参构造方法2");
	}
	
	public A(B b) {
		System.out.println("A有参构造方法1");
		System.out.println("A有参构造方法2");
	}
}
public class B extends A{
	static {
		System.out.println("B-static");
	}
	{
		System.out.println("B-not-static");
	}
	public B() {
		System.out.println("B-construct");
	}
}
public class Test {
public static void main(String[] args) {
		new B();
	}
}

执行结果:

a-static1
a-static2
B-static
a-not-static1
a-not-static2
A无参构造方法1
A无参构造方法2
B-not-static
B-construct

无继承,有层次:

public class A {
	static {
		new B();
		System.out.println("a-static1");
		System.out.println("a-static2");
	}
	{
		System.out.println("a-not-static1");
		System.out.println("a-not-static2");
	}
	public A() {
		System.out.println("A无参构造方法1");
		System.out.println("A无参构造方法2");
	}
	
	public A(B b) {
		System.out.println("A有参构造方法1");
		System.out.println("A有参构造方法2");
	}
}
public class B {
	static {
		System.out.println("B-static");
	}
	{
		System.out.println("B-not-static");
	}
	public B() {
		System.out.println("B-construct");
	}
}
public class Test {
public static void main(String[] args) {
	new A();
	}
}

执行结果:

B-static
B-not-static
B-construct
a-static1
a-static2
a-not-static1
a-not-static2
A无参构造方法1
A无参构造方法2

按照规律先执行A的static块,初始化完B()才会去接着执行。

 

再来一个例子:

public class A {
	static {
		new A();
		System.out.println("a-static1");
		System.out.println("a-static2");
	}
	{
		System.out.println("a-not-static1");
		System.out.println("a-not-static2");
	}
	public A() {
		System.out.println("A无参构造方法1");
		System.out.println("A无参构造方法2");
	}
	
	public A(B b) {
		System.out.println("A有参构造方法1");
		System.out.println("A有参构造方法2");
	}
}
public class Test {
public static void main(String[] args) {
	new A();
	}
}

结果:

a-not-static1
a-not-static2
A无参构造方法1
A无参构造方法2
a-static1
a-static2
a-not-static1
a-not-static2
A无参构造方法1
A无参构造方法2

先去执行A的static块,然后static块中有new A()的操作,所以去执行,但是static块已经被初始化了,所以不执行,执行非静态代码块和构造函数,执行完static块中的new A()操作了,然后接着执行。。。(省略)

 

如果我的层次放在构造函数中会怎么样?

public class A {
	static {
		System.out.println("a-static1");
		System.out.println("a-static2");
	}
	{
		System.out.println("a-not-static1");
		System.out.println("a-not-static2");
	}
	public A() {
		System.out.println("A无参构造方法1");
		System.out.println("A无参构造方法2");
	}
	
	public A(B b) {
		System.out.println("A有参构造方法1");
		System.out.println("A有参构造方法2");
	}
}
public class B {
	static {
		System.out.println("B-static");
	}
	{
		System.out.println("B-not-static");
	}
	public B() {
		System.out.println("B-construct");
	}
}
public class Test {
public static void main(String[] args) {
	new A(new B());
	}
}

执行结果:

a-static1
a-static2
B-static
B-not-static
B-construct
a-not-static1
a-not-static2
A有参构造方法1
A有参构造方法2

这个结果看的我有点吃惊,他首先执行A的static块这是没有问题的,但是后边在执行非static块之前先去把B整个初始化的流程给执行完了,然后再执行下面步骤。由于本人水平有限,暂时无法解释到虚拟机底层的流程到底是怎么执行的。还希望大佬们不吝赐教。

 

有层次,有继承:

public class A {
	static {
		new B();
		System.out.println("a-static1");
		System.out.println("a-static2");
	}
	{
		System.out.println("a-not-static1");
		System.out.println("a-not-static2");
	}

	public A() {
		System.out.println("A无参构造方法1");
		System.out.println("A无参构造方法2");
	}

	public A(B b) {
		System.out.println("A有参构造方法1");
		System.out.println("A有参构造方法2");
	}
}
public class B extends A{
	static {
		System.out.println("B-static");
	}
	{
		System.out.println("B-not-static");
	}
	public B() {
		System.out.println("B-construct");
	}
}
public class Test {
public static void main(String[] args) {
	new A();
	}
}

执行结果:

B-static
a-not-static1
a-not-static2
A无参构造方法1
A无参构造方法2
B-not-static
B-construct
a-static1
a-static2
a-not-static1
a-not-static2
A无参构造方法1
A无参构造方法2

与我们的逻辑无误。首先A去初始化,在static块中遇到了new B(),B又是A的子类,那B先去初始父类A,但是A的static块已经被执行过了。然后执行子类static块,然后父类非静态代码块以及构造方法,然后子类非静态代码块以及构造方法,然后Astatic块中的new B()就执行完了,然后顺序打印2个语句,然后就是A的非静态块以及构造方法了。

 

最后来分析一个困扰我2天例子:

public class Class1 {
	
	static {
		new Class2();
		System.out.println("666666666666666666");
	}
	{
		System.out.println("99999999999999999");
	}
	
	
	public Class1() {
		
		System.out.println("111111111111111111111");
	}
	
	public Class1(Class1 c1){
		System.out.println("==============");
	}
	
	public Class1(Class2 c2){
		System.out.println("++++++++++++++++++++");
	}
	
	public Class1(Class3 c3){
		System.out.println("---------");
	}

}
public class Class2 extends Class1{

}
public class Class3 extends Class2{

}
public class Test {
public static void main(String[] args) {
		new Class1(new Class3());
	}
}

执行结果:

99999999999999999
111111111111111111111
666666666666666666
99999999999999999
111111111111111111111
99999999999999999
---------

分析:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值