07、构造器 (constructor) -- 初始化成员变量

一、对象构造器 – () 方法


  • 创建对象,并为创建的对象成员变量 赋值(即:初始化对象)。

  • 执行时机:
    • new 操作符,调用对应的构造器,创建对象

1、构造器的定义


1、定义

  • 创建对象时,被 JVM 自动调用的特殊方法。
  • 注意:

2、声明构造器的语法

  • 语法:
【修饰符】构造器名(多个形参声明) {
    // 0~N 条可执行的语句。
}
  • 【修饰符】 – 可以省略。还可以是 public | protected | private。
  • 构造器名称 – 不能省略。必须与类名相同
  • 形参声明 – 形参名满足首字母小写 + 驼峰标识。多个形参声明之间用英文逗号隔开。

  • 构造器的执行体 – 执行体中放置可执行性的代码。代码从上到下执行。

3、构造器的特点:

  • 构造器的名称必须与类名相同
  • 构造器没有返回值也不能用 void 修饰
  • 构造器总是结合 new 操作符一起调用。
  • 每个类可以有一个以上的构造器。
  • 构造器可以有 0 个、1 个或多个参数。
public class User implements Serializable {
    private String name;
    private Short age;

    /**
     * 有参构造器
     * @param age
     * @param name
     */
    public User(Short age, String name) {
        this.age = age;
        this.name = name;
        
        // 可以有 return 语句。但是 return 后边不能有 返回值。
        return;
    }


    public static void main(String[] args) {
        User user = new User((short) 30, "张三");
        System.out.println(user);
    }
}

2、构造器的作用 – 构造并初始化对象


  • new 操作符,调用对应的构造器,创建对象,具体实现:
    • 1、去向内存申请内存。在对象内存被分配之后,JVM 给对象的 成员变量赋予 ****默认值
      + 数值类型 设置为 0、布尔值类型 设置为 false、引用类型为 null
      • JVM 给对象的 成员变量赋予 默认值发生在成员变量 被明确初始化之前
    • 2、先调用 对象的 实例初始化块,后调用 实例构造器() 方法)来完成 对象的初始化
      • 对象的初始化:为成员变量赋予 用户 / 程序 设定的值

1、去向内存中,申请内存并为对象的成员变量赋予 默认值

  • 构造器实例化块 没有为 实例成员变量 赋值时。
    • 执行 new 指令时,对象的成员变量都被赋予了 默认值。

  • 示例:
public class User {
    private String name;
    private short age;

    public User() {
    }

    public static void main(String[] args) {
        User user = new User();
        // 输出结果:    null    0
        System.out.println(user.name + "\t" + user.age);
    }
}

2、先调用 对象的 实例初始化块,后调用 实例构造器完成 对象的初始化

  • 示例:
public class User {
    private String name;
    private short age;

    {
        name = "张三";
        age = 31;
    }

    public User() {
    }

    public User(Short age, String name) {
        this.age = age;
        this.name = name;
    }

    public static void main(String[] args) {
        User user = new User();
        // 输出结果:   张三	31
        System.out.println(user.name + "\t" + user.age);

        User user1 = new User((short)30, "李四");
        // 输出结果:   李四	30
        System.out.println(user1.name + "\t" + user1.age);
    }
}

  • 无参构造器的字节码 – 先执行实例化块

  • 标准构造器的字节码 – 先执行实例化块

3、默认构造器、无参数构造器、有参数构造器、标准构造器


1、默认构造器

  • 在一个类没有声明任何构造器的情况下,编译器强制为该类添加的一个无参数的构造器
    • 该构造器仅仅调用父类的无参数构造器
  • 注意:
    • 一旦显式定义了‌任意构造器‌,默认构造器将不再自动生成
public class Person {
    // 没有显式定义构造器,编译器自动生成默认构造器:public Person() {}
}

2、无参数构造器

  • 开发者显式定义的、没有参数的构造器。可自定义初始化逻辑。
  • 注意:
    • 类中已定义有参构造器,但没显式定义无参构造器,则无法通过 new ClassName() 创建对象。
public class Person {
    public Person() {
        // 显式定义的无参构造器
        System.out.println("Person对象已创建");
    }
}

3、有参数构造器

  • 开发者显式定义的、带有参数的构造器,用于根据传入的参数初始化对象。
public class Person {
    private String name;
    private int age;

    // 显式定义的无参构造器
    public Person() {
        System.out.println("Person对象已创建");
    }

    // 有参构造器
    public Person(String name) {
        this.name = name;
    }

    // 有参构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

4、标准构造器

  • 所有实例字段 进行 赋值 的 有参构造器 称为 标准构造器 (canonical constructor)。
public class Person {
    private String name;
    private int age;

    // 显式定义的无参构造器
    public Person() {
        System.out.println("Person对象已创建");
    }

    // 有参构造器
    public Person(String name) {
        this.name = name;
    }

    // 有参构造器【标准构造器】
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

4、子类构造器 与 父类构造器


1、子类构造器 与 父类构造器 的 执行顺序

  • 当创建一个子类对象时:
    • 首先,自动调用父类的构造器初始化继承 父类的部分(如:父类的成员变量)。
      • 父类的 private 成员变量虽然无法直接访问。但是,可以通过提供的 getXxx() 方法访问。
    • 然后,再执行子类自己的构造器

2、父类构造器的调用规则:

  • 1、使用 super 调用父类构造器的语句必须是子类构造器的第一条语句。
  • 2、若子类构造器没有显式调用父类构造器(用 super()),Java 会默认调用父类的无参构造器
  • 3、若父类没有无参构造器,子类必须显式调用父类的某个构造器(用 super(xxx, ……))。
    • 否则,编译时将发生错误

5、一个构造方法中调用另一个构造方法


1、this() 调用

  • this() 调用 本类 的 无参构造方法
    • this() 必须是构造器的第一条语句。
  • this(实参列表) 调用 本类 的 有参构造方法
    • this(实参列表) 必须是构造器的第一条语句。

  • this() 用于调用当前类的其它构造器,实现代码复用

2、super() 调用

  • super()、super(实参列表) 则是调用 父类 的 构造方法
    • super()、super(实参列表) 必须是子类构造器的第一条语句。

二、类构造器 – () 方法


  • 类加载的初始化阶段就是执行 类构造器 () 方法 的过程。
  • 类构造器 () 编译器生成

1、不生成 类构造器 () 的场景


1、没有 静态变量 和 静态初始化块

public class User {
    private String name;
    private Short age;

    public static void main(String[] args) {

    }
}

2、没有 静态初始化块,有 静态变量 没有显示赋值

public class User {
    public static Class clazz;
    private String name;
    private Short age;

    public static void main(String[] args) {

    }
}

2、生成 类构造器 () 的场景


1、显式为 静态变量 赋值

public class User {
    public static Class clazz = null;
    private String name;
    private Short age;

    public static void main(String[] args) {

    }
}

2、显式 声明 静态代码块

public class User {
    private String name;
    private Short age;

    static{
        System.out.println("静态代码块!!!");
    }
    public static void main(String[] args) {

    }
}

3、类构造器 的 作用 和 执行时机


1、类构造器 的 作用

  • 在类加载时,执行 静态代码块 以及 完成 类变量 的 显式初始化 工作。

2、类构造器 执行时机

  • 类加载初始化 阶段。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值