Java练习——牛客网的一道类加载题目

class A {
	static {
		System.out.print("a");//只有在类加载时候会执行一次
	}
 
	public A() {
		System.out.print("x");
	}
 
}
 
class B extends A {
	static {
		System.out.print("b");
	}
 
	public B() {
		System.out.print("y");
	}
}
 
public class Test {
 
	public static void main(String[] args) {
 
		A ab = new B();
		System.out.println();
		ab = new B();
 
	}
 
}

输出结果:

abxy
xy

执行过程分析:

A ab = new B();

执行时候第一使用到A、B类,JVM发现没有加载A、B的信息,故先加载,由于B继承了A类,所以会先加载A再加载B,在加载的过程中会执行static块完成类的初始化。所以会先输出ab,此时创建B对象时候,会先执行A的构造方法在执行B的构造方法,故在输出xy,所以最后输出abxy。

再执行:

ab = new B();

这时发现已经加载过A、B的字节码了,故不会再加载了,所以不会输出ab,直接输出xy即可

 

如果代码修改为:

class A {
	static {
		System.out.print("a");// 只有在类加载时候会执行一次
	}
 
	public A() {
		System.out.print("x");
	}
 
}
 
class B extends A {
	static {
		System.out.print("b");
	}
 
	public B() {
		System.out.print("y");
	}
}
 
public class Test {
 
	public static void main(String[] args) {
 
		B ab = new B(); // 由于A ab = new B()=> B ab = new B()
		System.out.println();
		ab = new B();
	}
}

输出还是:

abxy
xy

当执行B ab = new B()时候,由于JVM事先就会知道B是继承至A的,所以需要先加载A,如果不先加载A的话,无法完成子类B的加载!所以类的加载顺序和构造器执行顺序一致,先父类再子类!

注意:容易糊涂的地方是,以为B ab =new B();以为创建B所以先加载B之后再加载A,这种理解就错误了,因为对于对象的创建是从父类开始的!

 

拓展:非静态代码块的执行顺序也是先父类,再子类!

但是非静态代码块执行顺序在静态代码块之后,构造器之前!

静态代码块只会执行一次(类加载时候执行),而非静态代码块会多在创建对象时候多次执行!

实践代码:

class A {
	static {
		System.out.print("a");// 只有在类加载时候会执行一次
	}
 
	{
		System.out.print("a-a");
	}
 
	public A() {
		System.out.print("x");
	}
 
}
 
class B extends A {
	static {
		System.out.print("b");
	}
	{
		System.out.print("b-b");
	}
 
	public B() {
		System.out.print("y");
	}
}
 
public class Test {
 
	public static void main(String[] args) {
 
		B ab = new B(); // 由于A ab = new B()=> B ab = new B()
		System.out.println();
		ab = new B();
	}
}

输出结果:

aba-axb-by
a-axb-by

 

如果两个类没有继承关系的话,类的加载顺序就是按照代码的执行顺序进行加载的。

class C {
	static {
		System.out.print("c");
	}
 
	public C() {
		System.out.print("x");
	}
 
}
 
 
class D {
	static {
		System.out.print("d");
	}
 
	public D() {
		System.out.print("y");
	}
 
}
 
 
public class Test1 {
	
	public static void main(String[] args) {
		
		C c=new C();
		System.out.println();
		D d=new D();
		
		
	}
 
}

输出结果:

cx
dy

 

你可能感兴趣的:(Java基础笔记)