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