非静态代码块和实例初始化过程

1 非静态代码块

非静态代码块特点

①可以为实例变量(非静态的属性)初始化

②每次创建对象的时候,都会执行一次,且先于构造器执行

③若有多个非静态的代码块,那么按照定义的顺序从上到下依次执行

④代码块中既可以调用非静态的变量和方法,也可以可以调用静态的变量和方法

测试代码:

public class BlockTest {
    public static void main(String[] args) {
        MyClass my1 = new MyClass();
        //MyClass my2 = new MyClass("java");
    }
}

class MyClass {
    private String str;

    {
        System.out.println("非静态代码块1");
    }

    public MyClass() {
        System.out.println("无参构造");
    }

    public MyClass(String str) {
        this.str = str;
        System.out.println("有参构造");
    }

    {
        System.out.println("非静态代码块2");
    }
}

运行结果

非静态代码块1
非静态代码块2
无参构造

2 实例初始化

实例初始化过程:创建对象时,为对象进行初始化的操作
①为成员变量显式赋值
②执行非静态代码块
③执行构造器

Java编译器会把这三个部分的代码,合成一个叫做 <init>([形参列表]) 实例初始化方法
即编译后的.class字节码信息中,是没有构造器这个概念。

<init>([形参列表]) 实例初始化方法的代码就是由三个部分组成:
①成员变量显式赋值的代码
②非静态代码块中的代码
③构造器中的代码

其中①和②按定义顺序依次执行,③最后执行。

而且,有几个构造器,就会有几个实例初始化方法。那么当你创建对象的时候,调用对应的构造器时,其实执行的是对应的实例初始化方法 <init>([形参列表])

代码示例:

public class InitTest {
    public static void main(String[] args) {
        Demo d1 = new Demo();
        //Demo d2 = new Demo("java");
    }
}

class Demo{

    {
        System.out.println("非静态代码块1");
    }

    private String str = assign();//调用方法,为str进行显式赋值

    public Demo(){
        System.out.println("无参构造");
    }
    public Demo(String str){
        this.str = str;
        System.out.println("有参构造");
    }

    {
        System.out.println("非静态代码块2");
    }

    public String assign(){
        System.out.println("为成员变量赋值");
        return "hello";
    }
}

3 子类实例初始化

(1)先执行父类的实例初始化方法

它由三部分组成:

  1. 成员变量的显式赋值

  2. 非静态代码块

  3. 构造器

(2)再执行子类的实例初始化方法

它由三部分组成:

  1. 成员变量的显式赋值

  2. 非静态代码块

  3. 构造器

super()或super(实参列表) 表面是调用父类的构造器,其实是调用父类对应的实例初始化方法

super()或super(实例列表) 表面是在子类构造器的首行,其实是在子类实例初始化方法的首行

代码示例:

public class InitTest2 {
    public static void main(String[] args) {
        Son s = new Son();
    }
}

class Father {
    private String strFather = assignFather();
    
    {
        System.out.println("父类的非静态代码块");
    }
    
    public Father(){
        System.out.println("父类的无参构造");
    }
    
    public String assignFather(){
        System.out.println("父类的assignFather()");
        return "father";
    }
}

class Son extends Father {
    private String strSon = assignSon();
    
    {
        System.out.println("子类的非静态代码块");
    }
    
    public Son(){
        //super() ==> 调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
        System.out.println("子类的无参构造");
    }

    public String assignSon(){
        System.out.println("子类的assignSon()");
        return "son";
    }
}

运行结果:

父类的assignFather()
父类的非静态代码块
父类的无参构造
子类的assignSon()
子类的非静态代码块
子类的无参构造

子类为成员变量显式赋值方法重写父类显式赋值方法时,调用的子类重写的方法,代码示例:

public class InitTest3 {
    public static void main(String[] args) {
        Son s = new Son();
    }
}

class Father {
    private String strFu = assign();

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

    public Father(){
        System.out.println("父类的无参构造");
    }

    public String assign(){
        System.out.println("父类的assign()");
        return "father";
    }
}

class Son extends Father {
    private String strSon = assign();

    {
        System.out.println("子类的非静态代码块");
    }

    public Son(){
        //super()  ==>调用父类的实例初始化方法,而且它在子类实例初始化方法的首行
        System.out.println("子类的无参构造");
    }

    public String assign(){
        System.out.println("子类的assign()");
        return "son";
    }
}

运行结果:

子类的assign()
父类的非静态代码块
父类的无参构造
子类的assign()
子类的非静态代码块
子类的无参构造

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值