Day06 (加载类创建对象)

王道训练营Java31期

Day02 (oop部分:加载类、加载类并创建对象、成员变量、静态代码块、默认构造方法、单参数构造方法)

package com.xy.java.day06.oop_block_by_xy.block12.static3;

/**
 * @program: day06_javase_oop2_block
 * @description: 静态代码块的执行
 * @author: xj992adolphxy@163.com
 * @create: 2021-04-04 16:51
 **/

/**
 * 静态代码块
 * 位置:成员位置
 * 语法:static{}
 * 作用:加载类时执行,给静态成员变量赋值
 * 
 * 记忆点1.特殊情况:静态代码块写在成员变量上面
 * 不要这样写,面试官问就正常顺序说,自己写代码不这样写
 * 
 * 记忆点2.静态代码块能不能给普通成员变量赋值
 * 不能。
 * (所谓普通成员变量,就是成员位置的单行成员变量赋值语句中的变量,不加表示静态的关键字static)
 * 不要给自己造成记忆负担,以后不要说普通成员变量,就说成员变量
 * 成员变量赋值语句,是类声明、创建对象之后,才会执行的
 * 要创建对象
 * 
 * 记忆点3.静态代码块中能不能写this关键字
 * 不能。
 * 首次加载类到方法区,只是初始化了静态变量
 * 一个对象的创建完成3步:
 * 1.加载类。这里执行静态代码块
 * 2.执行成员位置语句。
 * 3.执行构造方法
 * 4.回到创建对象语句。这里产生能用this的对象名
 * 
 * 记忆点4.静态代码块执行次数
 * 一次程序的运行期间,只执行一次,不会重复执行
 * 
 * 记忆点5.静态代码块和静态成员
 * 1.都不能调用成员变量和成员方法
 * 2.静态代码块用的地方不多,除非程序需要复杂初始化
 * 3.规范:静态成员变量定义语句在前,静态代码块在后
 * 4.成员位置的构造代码块,可以给静态成员赋值
 * 5.(再次重申)静态代码块,不可以给普通成员变量赋值
 * (静态代码块位置:成员位置附近,一般在静态变量赋值语句之后,位于类头上部位置)
 * 6.静态代码块、构造代码块给同一个静态成员变量赋值:
 * -->先执行静态代码块
 * -->后执行构造代码块,这里是最终值
 * 原因:
 * 静态代码块在首次类加载时执行
 * 构造代码块在类加载、对象创建过程中执行
 * 一前一后
 */


public class Demo {
    public static void main(String[] args) {
        Dog.age = 10;
        //Dog.age = 10;
        //Dog.age = 10;

        Dog d = new Dog(18);
        Dog d2 = new Dog(18);
        Dog d3 = new Dog(18);
        Dog d4 = new Dog(18);
        Dog d5 = new Dog(18);

        System.out.println(Dog.age);

    }
}

class Dog {
    int a;
    static int age = 1;

    {
        age = 29;
    }

    static {
        age = 2;
        //System.out.println(this.a);
        //cannot be referenced from a static context
    }

    public Dog() {
        System.out.println("构造函数调用");
    }

    public Dog(int age) {
        Dog.age = age;//构造方法中,可以调用类的静态变量,并赋值
    }
}

代码单步调试

第一步:打断点

包含main()方法的类中psvm中的第一行。一般main()方法中第一行都要设置断点

类中静态成员赋值行、静态代码块中第一行、每个构造方法中第一行。

第二步:调试

对每一步跳转说明跳转原因。每次点击蓝色向下箭头(单步跳入)

<1>执行Demo类中main()方法,执行第57行代码:
没有显式声明Dog类,直接调用Dog类静态成员变量age。

加载Dog类到JVM内存中,跳转到Dog类的空参数构造方法(默认构造方法),暂不执行构造,然后从类头开始向下找静态成员。

找到第1个静态成员变量赋值语句

切换到Debugger标签检查变量值变化:

有默认初始化,int类型age默认赋初值0

继续查找并执行静态成员变量(如果有),找到1个静态代码块:

代码块中

age赋值:对静态成员变量赋值

插曲:什么时候用this

(输出当前对象的成员变量a的值。这里还没有经过创建对象、成员变量赋值、构造方法,所以这里不能用this)

至此静态成员、静态代码块赋值语句执行结束,回到main()方法中刚才调用Dog类的语句:

Debugger标签中检查变量值变化:age是2,马上就会变成10

至此,调用类Dog的静态成员变量的赋值语句执行结束。进入下一行

创建Dog类对象d,调用对应参数构造方法。跳转到Dog类的单参数构造方法,但是暂时不执行。

跳到Dog类头

从上到下,执行成员变量、代码块

找到第1个成员位置语句:成员变量赋值语句,是声明没有赋值,默认赋初值0。没有体现在截图中

找到第2个成员位置语句:代码块(大括号包起来的部分),执行里面第1句。age赋值29

成员变量语句全部执行完,跳转到刚才没有执行的构造方法

执行这个构造方法。传入age参数18

构造方法中第1句:赋值Dog类的静态成员变量age,age从29变成18

至此构造方法执行结束。回到main()方法刚才创建类对象语句

继续执行之后的创建对象语句。之后的跳转类似。

本次调试主要意义:理解类加载、类加载之后创建对象、成员变量位置的代码块中可以修改静态成员变量

本次调试缺点:没有用断点体现构造方法的选择

后续要完成:对于单参数、多参数的创建对象语句,用断点截图体现出调用对应参数的构造方法or默认构造方法。

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值