【JavaSE专栏58】对象构造函数及优先级问题,谁先谁后一目了然

简介: 【JavaSE专栏58】对象构造函数及优先级问题,谁先谁后一目了然


一、什么是构造函数

在 Java 中,构造函数是一种特殊的方法,用于创建和初始化对象

构造函数的主要作用是为对象分配内存空间并初始化对象的实例变量

构造函数具有以下 6 66 个特点,请同学们认真学习。

  1. 构造函数的名称与所在类的名称相同。
  2. 构造函数没有返回类型,包括 void 类型。
  3. 构造函数在创建对象时自动被调用,不能手动调用。
  4. 构造函数可以带有参数,用于接收外部传递的初始化数据。
  5. 如果一个类没有定义构造函数,Java 编译器会默认生成一个无参构造函数。
  6. 如果一个类定义了有参构造函数,Java 编译器则不会再自动生成无参构造函数。

构造函数的作用主要包括以下 3 33 个方面,请同学们认真学习。

  1. 为对象分配内存空间:构造函数在创建对象时,会在堆内存中为对象分配内存空间。
  2. 初始化对象的实例变量:构造函数可以在对象创建后,对对象的实例变量进行初始化操作,确保对象在创建后处于一种可用状态。
  3. 执行其他必要的初始化操作:构造函数可以执行其他必要的初始化操作,如打开文件、建立数据库连接等。

以下是一个示例代码,展示了一个简单的构造函数用法,请同学们认真学习。

public class Person {
    private String name;
    private int age;
    // 无参构造函数
    public Person() {
        name = "";
        age = 0;
    }
    // 带参构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // Getter和Setter方法省略
    public static void main(String[] args) {
        // 使用构造函数创建对象并初始化
        Person person1 = new Person(); // 使用无参构造函数
        Person person2 = new Person("Alice", 25); // 使用带参构造函数
    }
}

在上述示例中,Person 类定义了一个无参构造函数和一个带参构造函数,通过构造函数,可以创建并初始化 Person 对象。


二、无参构造函数和有参构造函数

下面是一个示例代码,展示了无参构造函数和有参构造函数的用法,请同学们认真学习。

public class Person {
    private String name;
    private int age;
    // 无参构造函数
    public Person() {
        name = "";
        age = 0;
    }
    // 有参构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    // Getter和Setter方法省略
    public static void main(String[] args) {
        // 使用无参构造函数创建对象并初始化
        Person person1 = new Person();
        // 使用有参构造函数创建对象并初始化
        Person person2 = new Person("Alice", 25);
    }
}

在上述示例中,Person 类定义了一个无参构造函数和一个有参构造函数。通过无参构造函数可以创建一个默认的 Person 对象,然后可以通过调用 setter 方法来设置对象的属性。而通过有参构造函数,可以直接在创建对象的同时进行属性的初始化,省去了调用 setter 方法的步骤。


三、构造函数调用的优先级

在 Java 中,构造函数调用的优先级顺序如下,请同学们认真学习。

  1. 子类构造函数会先调用父类的无参构造函数(如果父类有无参构造函数),以确保父类对象的初始化。
  2. 子类构造函数可以通过使用 super 关键字来调用父类的有参构造函数,以进行父类属性的初始化。

下面是一个示例代码,展示了构造函数调用的优先级顺序,请同学们认真学习。

public class Animal {
    private String name;
    public Animal() {
        System.out.println("Animal类的无参构造函数");
    }
    public Animal(String name) {
        this.name = name;
        System.out.println("Animal类的有参构造函数");
    }
}
public class Dog extends Animal {
    private String breed;
    public Dog() {
        System.out.println("Dog类的无参构造函数");
    }
    public Dog(String breed) {
        super("某某动物");
        this.breed = breed;
        System.out.println("Dog类的有参构造函数");
    }
    public static void main(String[] args) {
        Dog dog1 = new Dog();
        System.out.println("--------------------");
        Dog dog2 = new Dog("某某犬种");
    }
}

输出结果为:

Animal类的无参构造函数
Dog类的无参构造函数
--------------------
Animal类的有参构造函数
Dog类的有参构造函数

从输出结果可以看出,当创建 Dog 对象时,首先会调用父类 Animal 的无参构造函数,然后才调用子类 Dog 的无参构造函数。而当使用 super 关键字调用父类的有参构造函数时,会先调用父类的有参构造函数,然后再调用子类的有参构造函数。这样可以确保父类对象的初始化。


四、构造函数的使用场景

构造函数在 Java 中有以下 5 55 个使用场景,请同学们认真学习。

  1. 创建对象:构造函数用于创建对象并分配内存空间。通过构造函数可以实例化一个类,并初始化对象的属性。
  2. 初始化对象的属性:构造函数可以在对象创建后,对对象的实例变量进行初始化操作,确保对象在创建后处于一种可用状态。
  3. 执行其他必要的初始化操作:构造函数可以执行其他必要的初始化操作,如打开文件、建立数据库连接等。可以在构造函数中执行一些必要的预处理或初始化操作,以确保对象在使用前处于正确的状态。
  4. 提供重载的构造函数:通过提供多个构造函数,可以根据不同的参数组合来创建对象。这样可以方便地根据不同的需求创建不同配置的对象,提高了代码的灵活性和可复用性。
  5. 实现继承关系中的构造函数链:子类的构造函数可以通过使用 super 关键字来调用父类的构造函数,以确保父类对象的初始化。通过构造函数链的方式,可以一层一层地调用父类的构造函数,确保所有父类的属性都得到正确的初始化。

总的来说,构造函数是用来创建和初始化对象的重要方法。它在对象的生命周期中起着关键的作用,确保对象在创建后处于预期的状态,为后续的操作提供正确的基础。


五、构造函数优先级面试题

问题:假设有一个类A和一个类B,类B继承自类A,且它们都有无参构造函数和有参构造函数。当创建一个类B的对象时,构造函数的调用优先级是什么?

回答:

  1. 首先,会调用类 B 的有参构造函数(如果存在)。
  2. 如果类 B 的有参构造函数中使用了 super 关键字调用了父类 A 的有参构造函数,则会先调用类 A 的有参构造函数。
  3. 如果类 B 的有参构造函数中未使用 super 关键字调用父类 A 的有参构造函数,则会紧接着调用类 A 的无参构造函数。
  4. 最后,类B的有参构造函数中的初始化代码将会执行。

这样可以保证父类 A 和子类 B 的构造函数都得到正确的调用和执行,确保对象在创建时具有正确的状态。

需要注意的是,如果类 A 和类 B 都没有有参构造函数,那么会直接调用它们的无参构造函数,没有其他额外的构造函数调用逻辑。


六、总结

本文讲解了 Java 中对象构造函数及优先级问题,并给出了样例代码,在下一篇博客中,将讲解 Java 中方法重写及优先级问题。


相关文章
|
6月前
|
Java
【Java每日一题】— —第二十二题:类名作参数进行方法调用的传递问题。
【Java每日一题】— —第二十二题:类名作参数进行方法调用的传递问题。
|
安全 Java 开发者
Java单例模式7种写法,你是不是有用错过?
Java单例模式7种写法,你是不是有用错过?
52 0
|
13天前
|
Java Kotlin
​ Kotlin教程笔记(13) - 类及成员的可见性
​ Kotlin教程笔记(13) - 类及成员的可见性
41 5
|
3月前
|
Java
【Java基础面试十八】、说一说重写与重载的区别
这篇文章阐述了Java中重写与重载的区别:重载是同一个类中方法名相同但参数列表不同的方法之间的关系,而重写是子类中方法与父类中相同方法名和参数列表的方法之间的关系,且子类的返回值应小于等于父类,访问修饰符应大于等于父类。
【Java基础面试十八】、说一说重写与重载的区别
|
5月前
|
存储 Java
心得经验总结:浅谈Java类中的变量初始化顺序
心得经验总结:浅谈Java类中的变量初始化顺序
32 1
|
5月前
|
存储 Java 程序员
JavaSE——面向对象基础(1/4)-面向对象编程、程序中的对象、对象的产生、对象的执行原理、类和对象的一些注意事项
JavaSE——面向对象基础(1/4)-面向对象编程、程序中的对象、对象的产生、对象的执行原理、类和对象的一些注意事项
51 7
|
5月前
|
存储 Java
JavaSE 面向对象程序设计初级 静态static 包package 常量final 代码块 代码实操理论内存原理详解
JavaSE 面向对象程序设计初级 静态static 包package 常量final 代码块 代码实操理论内存原理详解
34 0
|
Java 编译器
【面试题精讲】如果一个类没有声明构造方法,该程序能正确执行吗?
【面试题精讲】如果一个类没有声明构造方法,该程序能正确执行吗?
|
设计模式 Java 安全
Java中包的作用以及使用、访问权限、单例/多例设计模式、枚举和异常(附带相关面试题)
本章节讲述以下方面知识点 1.包的作用以及使用 2.单例/多例化设计模式 3.枚举 4.访问权限2.异常
79 0
Java中包的作用以及使用、访问权限、单例/多例设计模式、枚举和异常(附带相关面试题)
【JavaSE专栏65】内部类的使用,定义在其他类内部的类
【JavaSE专栏65】内部类的使用,定义在其他类内部的类