java父类和子类的调用顺序

在了解java类加载机制的时候,我们有时候会遇到一些谁先谁后的问题,我们当然不能一眼看出来,我们需要实践代码来总结结论
下面是我封装好两个类

public class People {
    private String name;
    private int age;
    private static  String a = father();
    public static String father()
    {
        System.out.println("父类静态变量");
        return "父类静态变量";
    }
    static {
        System.out.println("父类静态块");
    }
    {
        System.out.println("父类非静态块");
    }
    public People(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public People(){
        System.out.println("父类构造方法");
    }
    public void speak(){
        System.out.println("我是人");
    }
}
public class Student extends People {
    private String stuNo;
    static {
        System.out.println("子类静态块");
    }
    private static  String b = child();
    public static String child()
    {
        System.out.println("子类静态变量");
        return "子类静态变量";
    }

    public Student(String name, int age, String stuNo) {
        super(name, age);
        this.stuNo = stuNo;
    }
    public Student(String stuNo) {
        this.stuNo = stuNo;
    }
    public Student(){
        System.out.println("子类构造方法");
    }

    {
        System.out.println("子类非静态块");
    }
    @Override
    public void  speak(){
        System.out.println("我是学生");
    }
}

我们新建了两个学生对象,并且执行了代码的结果如图所示:

 public static void main(String[] args) {
        Student s1 = new Student();
        System.out.println("================================");
        Student s2 = new Student();

    }

在这里插入图片描述

我们有了代码运行的基础可以总结出来以下几点:

1.所有的静态变量,无论是父类还是子类只会被加载一次。
其中 静态代码块,在类被加载的时候运行,因此只加载一次,且优先于其他变量,常用于运行一些项目启动时需要运行的代码,比如加载项目需要的系统资源等等。静态变量 所有该类的对象共同具有的属性。

2.静态变量的加载顺序与代码的书写顺序有关
我们可以发现父类与子类的静态块与静态变量加载的顺序不一样,因为我们的书写顺序不同。

3.代码块顺序优先于构造方法
构造代码块(代码块),在创建对象的时候执行,且先于构造函数执行。目的也是用于初始化对象,关于和构造函数的不同,我的理解是,如果有多个不同参数的构造函数,就可以提取他们共同的初始化语句到构造代码块,减少重复。

4.如果一个类具有父类,在类加载的时候都是先加载父类的方法(相当于构造了一个父类对象)

  1. 子类继承父类后,获取到父类的属性和方法,这些属性和方法在使用前必须先初始化,所以须先调用父类的构造器进行初始化。
  2. 在子类构造器的第一行会隐式的调用 super();,即调用父类的构造器
    如果父类中没有定义空参的构造器,则必须在子类的构造器的第一行显示的调用super(参数); ,以调用父类中构造器
    如果子类中构造器的第一行写了this();,则就隐式的super();会消失,因为super()和this()都只能在构造器的第一行定义

下面我们更改测试代码:

 		People p1 =new People();
        System.out.println("================================");
        Student s1 = new Student();
        System.out.println("================================");
        Student s2 = new Student();
 

在这里插入图片描述

!!再一次向我们证明

不管是父类还是子类加载(静态变量和静态语句块)都只能加载一次。
不管是父类还是子类加载(非静态变量和非静态语句块和构造函数)都可重复加载

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值