结论
在刷Java基础题时,碰到类的加载顺序题目,总是被各种成员变量和方法的初始化搞得一脸懵逼。因此仔细研究了一下父子类中各种成分的加载顺序。顺序如下
- 父类的静态成员变量
- 父类的静态代码块
- 子类的静态成员变量
- 子类的静态代码块
- 父类的普通成员变量
- 父类的一般代码块
- 父类的构造方法
- 子类的普通成员变量
- 子类的一般代码块
- 子类的构造方法
代码
Talk is cheap, show me the code!
package javaBases.oo.initialization;
/**
* @Description TODO
* @Author wendyma
* @Date 2021/12/16 7:58
* @Version 1.0
*/
public class Dog extends Animal{
static int age = getAge();
private String name = getDogName();
{
System.out.println("子类Dog的一般代码块");
}
static {
System.out.println("子类Dog的静态代码块");
}
public Dog(){
this.name = "Dog";
System.out.println("子类Dog的构造方法");
}
public static int getAge(){
System.out.println("子类Dog的静态成员变量");
return 2;
}
public String getDogName(){
System.out.println("子类Dog的普通成员变量");
return "dog";
}
public static void printAge(){
System.out.println("子类Dog的静态方法");
}
public String printName(){
System.out.println("子类Dog的普通方法");
return name;
}
public static void main(String[] args) {
Animal dog = new Dog();
System.out.println("静态方法是否具有多态性?-------------------");
dog.printAge();
}
}
class Animal{
static int age = getAge();
private String name = getName();
{
System.out.println("基类Animal的一般代码块");
}
static {
System.out.println("基类Animal的静态代码块");
}
public Animal(){
this.name = "Animal";
System.out.println("基类Animal的构造方法");
}
public static int getAge(){
System.out.println("基类Animal的静态成员变量");
return 2;
}
public String getName(){
System.out.println("基类Animal的普通成员变量");
return "dog";
}
public static void printAge(){
System.out.println("基类Animal的静态方法");
}
public String printName(){
System.out.println("基类Animal的普通方法");
return name;
}
}
输出结果
基类Animal的静态成员变量
基类Animal的静态代码块
子类Dog的静态成员变量
子类Dog的静态代码块
基类Animal的普通成员变量
基类Animal的一般代码块
基类Animal的构造方法
子类Dog的普通成员变量
子类Dog的一般代码块
子类Dog的构造方法
静态方法是否具有多态性?-------------------
基类Animal的静态方法
Process finished with exit code 0
并且从上述输出结果可以看到 dog.printAge() 实际调用的是 Animal类的 printAge() 方法,没有根据dog 的实际类型调用Dog类的静态方法 printAge(),这表明静态方法不具有多态性。