子继承父,在创建对象时,对资源加载的过程的理解
说明:
子类构造器调用this();会调用子类本身的空参构造器。
子类构造器调用spuer();会调用父类的空参构造器,调用spuer( xxx)会父类有参构造器
1. 一个new Leaf();
package com.zy.controller;
/**
* 先父后子,静态先行
*/
public class Root {
String name;
Integer age;
static {
System.out.println("Root的静态代码块");
}
{
System.out.println("Root的非静态代码块");
}
public Root() {
System.out.println("Root的空参构造器");
}
public Root(String name, Integer age) {
this();
System.out.println("Root的非空参构造器");
this.name = name;
this.age = age;
}
}
class Mid extends Root {
static {
System.out.println("Mid的静态代码块");
}
{
System.out.println("Mid的非静态代码块");
}
public Mid() {
System.out.println("Mid的空参构造器");
}
public Mid(String name, Integer age) {
this();
System.out.println("Mid的非空参构造器");
this.name = name;
this.age = age;
}
}
class Leaf extends Mid {
static {
System.out.println("Leaf的静态代码块");
}
{
System.out.println("Leaf的非静态代码块");
}
public Leaf() {
super("名字",18);
System.out.println("Leaf的空参构造器");
}
}
class ExtendsTest {
public static void main(String[] args) {
new Leaf();
}
}
控制台输出:
Root的静态代码块
Mid的静态代码块
Leaf的静态代码块
Root的非静态代码块
Root的空参构造器
Mid的非静态代码块
Mid的空参构造器
Mid的非空参构造器
Leaf的非静态代码块
Leaf的空参构造器
解析:
在new Leaf();
时,Leaf有父类Mid类,所以先加载Mid类,但是mid类也有父类Root类,所以加载root类,Root类有Object类,所以先加载Object类,再加载root类,再加载mid,之后是leaf。
顺序是 Object类 -> Root类 -> Mid类 -> Leaf类
,
加载类时的加载顺序:静态资源 -> 非静态代码块 -> 构造器。
所以运行顺序是
Root静态代码块 -> Mid静态代码块 ->Leaf静态代码块 -> Root非静态代码块 -> Root构造器 -> Mid非静态代码块 -> Mid空参构造器 -> Mid非空参构造器 -> Leaf的非静态代码块 -> Leaf的空参构造器
2. 两个new Leaf();
package com.zy.controller;
/**
* 先父后子,静态先行
*/
public class Root {
String name;
Integer age;
static {
System.out.println("Root的静态代码块");
}
{
System.out.println("Root的非静态代码块");
}
public Root() {
System.out.println("Root的空参构造器");
}
public Root(String name, Integer age) {
this();
System.out.println("Root的非空参构造器");
this.name = name;
this.age = age;
}
}
class Mid extends Root {
static {
System.out.println("Mid的静态代码块");
}
{
System.out.println("Mid的非静态代码块");
}
public Mid() {
System.out.println("Mid的空参构造器");
}
public Mid(String name, Integer age) {
this();
System.out.println("Mid的非空参构造器");
this.name = name;
this.age = age;
}
}
class Leaf extends Mid {
static {
System.out.println("Leaf的静态代码块");
}
{
System.out.println("Leaf的非静态代码块");
}
public Leaf() {
super("名字",18);
System.out.println("Leaf的空参构造器");
}
}
class ExtendsTest {
public static void main(String[] args) {
new Leaf();
System.out.println("---------------------------");
new Leaf();
}
}
控制台输出:
Root的静态代码块
Mid的静态代码块
Leaf的静态代码块
Root的非静态代码块
Root的空参构造器
Mid的非静态代码块
Mid的空参构造器
Mid的非空参构造器
Leaf的非静态代码块
Leaf的空参构造器
---------------------------
Root的非静态代码块
Root的空参构造器
Mid的非静态代码块
Mid的空参构造器
Mid的非空参构造器
Leaf的非静态代码块
Leaf的空参构造器
Process finished with exit code 0
解析:
第一次 new Leaf();
已经加载过静态代码块,第二次 new Leaf();
不需要再加载静态代码块,两个new的对象共用一个常量池
里面的静态资源。其他的和第一个new Leaf();
一样