天天看点

代码块、静态代码块、静态方法、构造方法顺序

面试时经常会碰到一些关于静态方法加载的试题,主要是考察面试者对于子父类加载顺序的了解,今天做一节小结,记录一些。总是感觉代码不写出来自己测试的话,感觉总是不牢靠,所有把今天的代码记录一下。

package 静态static;

public class Statictest {

public static void main(String[] args) {

B b = new B(“b”);

}

}

class A {

public String name;

public A() {
	// this.name = name;
	System.out.println("类A new的无参构造方法此时name=" + name);
}
public A(String name) {
	this.name = name;
	System.out.println("类A new时参数为" + name + "的构造方法");
}
 D d=new D("a");

{
	System.out.println("A父类代码块");
}
static {
	System.out.println("A父类静态代码块");
}

public static String eat() {
	return "A静态方法";
}

public String say() {
	return "A非静态方法";
}
           

}

class B extends A {

public String name;

public B(String name) {

this.name = name;

System.out.println(“类B new时参数为” + name + “的构造方法”);

}

D d=new D(“b”);

{

System.out.println(“B子类代码块1”);

}

static {

System.out.println(“B子类静态代码块1”);

}

{

System.out.println(“B子类代码块2”);

}

static {

System.out.println(“B子类静态代码块2”);

}

public static String eat() {

return “B子类静态方法”;

}

public String say() {

return “B子类非静态方法”;

}

public static String drink() {

return “B子类静态方法”;

}

public String play() {

return “B子类非静态方法”;

}

}

class D {

public String name;

public D(String name) {

this.name = name;

System.out.println(name +“类中new D 时参数为” + name + “的构造方法”);

}

{

System.out.println(“生成D代码块”);

}

static {

System.out.println(“生成D静态代码块”);

}

public static String eat() {
	return "D静态方法";
}
public String say() {
	return "D非静态方法";
}
           

}

//执行后的结果如下:

A父类静态代码块

B子类静态代码块1

B子类静态代码块2

生成D静态代码块

生成D代码块

a类中new D 时参数为a的构造方法

A父类代码块

类A new的无参构造方法此时name=null

生成D代码块

b类中new D 时参数为b的构造方法

B子类代码块1

B子类代码块2

类B new时参数为b的构造方法

误区小结:

1、之前把静态方法和静态代码块混淆了通过这个例子有理顺一下,new对象时静态方法是不会调用的。而静态代码块将执行。

2、这个例子中有一个需要注意的就是,子类的构造方法需要父类必须有无参构造方法(当写过有参构造方法时,默认的无参构造方法就不存在,需要自己添加)。

3、静态代码块只有在第一次加载类时加载,此后不在加载,也就是说只加载一次,但是代码块每次new对象时都会加载。(代码中new了两次D类对象。)

继续阅读