欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

实践探索JAVA初始化过程

程序员文章站 2024-01-03 21:21:16
...

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
---------

分析:

实践探索JAVA初始化过程

相关标签: java基础

上一篇:

下一篇: