Java——面向对象的编程学习之代码块

类的成员之一——代码块

  1. 代码块的作用:用来初始化类、对象
    在类中,代码块主要使用一对” {} “表示

    class test{
    	private int age;
    	// 以下为代码块
    	{
    		age = 18;
    	}
    }
    
  2. 代码块如果有修饰的话,只能使用static

  3. 分类:静态代码块 vs 非静态代码块
    静态代码块
    内部可以有输出语句
    随着类的加载而执行,且只执行一次
    作用:初始化类的信息
    如果一个类中定义了多个静态代码块,谁先定义谁先执行
    静态代码块只能调用静态的属性、方法,不能调用非静态的

    public class BlockTest {
        @Test
        public void test1(){
            int age = TestBlock.age;   // 此时还没有创建对象
        }
    
    }
    
    class TestBlock{
        private String name;
        static int age = 19;
    
        static {
            System.out.println("这是静态代码块");
        }
    
    }
    

    上述代码中,定义了一个静态代码块,并且其随着类的加载而自动执行了代码块中的内容,输出了一条语句。

    非静态代码
    内部可以有输出语句
    随着对象的创建而执行
    每创建一个对象,就执行一次非静态代码块
    作用:可以在创建对象时,对对象的属性进行初始化
    非静态代码块可以调用静态的属性和方法

    public class BlockTest {
        @Test
        public void test1(){
            TestBlock t1 = new TestBlock();
            TestBlock t2 = new TestBlock();
        }
    
    }
    
    class TestBlock{
        private String name;
        static int age = 19;
        private double height;
    
        {
            System.out.println("这是非静态代码块");
            name = "Tom";
            height = 180.0;
        }
    }
    

    在上面的代码中,定义了一个非静态代码块,并创建了两个对象,由于非静态代码块是随着对象的创建而执行,因此,非静态代码块要被执行两次,共输出两条语句
    在这里插入图片描述

属性赋值位置及先后顺序

由于代码块中也可以对属性进行赋值,加上之前所讲的,对属性的赋值可以有以下几种方式:

  • ①默认初始化
  • ②显式初始化
  • ③构造器中初始化
  • ④有了对象以后,可以通过“对象.属性”或”对象.方法”的方式,进行赋值
  • ⑤在代码块中赋值

其先后顺序为:①——② / ⑤ ——③——④

代码块在子父类中执行的先后顺序

直接用代码解释:

public class BlockTest {
    public static void main(String[] args) {
        new Leaf();
    }

}

class Root{
    static {
        System.out.println("Root的静态代码块");
    }

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

    public Root() {
        System.out.println("Root的无参构造器");
    }
}

class Mid extends Root{
    static {
        System.out.println("Mid的静态代码块");
    }

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

    public Mid() {
        System.out.println("Mid的无参构造器");
    }

    public Mid(String str){
        System.out.println("Mid的有参构造器");
    }
}

class Leaf extends Mid{
    static {
        System.out.println("Leaf的静态代码块");
    }

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

    public Leaf() {
        super("hello");
        System.out.println("Leaf的无参构造器");
    }
}

代码输出结果:
在这里插入图片描述
解释:
程序的执行是从main函数开始的,在main函数中,执行了” new Leaf(); “这条语句,通过new,程序会调用Leaf类的构造器。
——>前文已经提到,代码块的执行要早于构造器,静态代码块随着类的加载而执行,非静态代码块随着对象的创建而执行。因此,在调用Leaf类的构造器之前,程序会先执行Leaf类的静态代码块。由于Leaf类继承于Mid类,而Mid类继承于Root类,所以程序前三条输出语句为” Root的静态代码块 “、” Mid的静态代码块 “、” Leaf的静态代码块 “。
——>在Leaf类的构造器中,由于Leaf继承于Mid类,因此会先调用Mid类的构造器。
——>同理,Mid类继承于Root类,所以会先调用Root类的构造器。而非静态代码块的执行要早于构造器,所以程序第四条输出语句为” Root的非静态代码块 “。
——>紧接着,程序就会调用Root的构造器,所以第五条输出” Root的无参构造器 “。Root类的相关操作执行完后,就会回到Mid类。
——>同理,Mid非静态代码块的执行要早于构造器,所以第六条输出” Mid的非静态代码块 “。由于,在Leaf类的构造器中,调用的是Mid类的有参构造器,所以第七条输出” Mid的有参构造器 “。
——>最后,回到Leaf类本身,程序先调用Leaf类的非静态代码块,输出” Leaf的非静态代码块 “,然后调用Leaf类的构造器,输出” Leaf的无参构造器 “。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

农夫三犭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值