怎么证明未显式定义构造方法时,编译器会自动生成无参的构造方法?

Posted 一朵花花

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了怎么证明未显式定义构造方法时,编译器会自动生成无参的构造方法?相关的知识,希望对你有一定的参考价值。

在和类和对象篇提到:
当没有显式定义构造方法,编译器会自动提供一个没有参数的构造方法
若类中显式定义了构造方法,则默认的无参构造不再产生

本篇博客就带大家一起来验证~


首先,显式定义构造方法:即 自己定义构造方法,非编译器提供默认构造方法

看是否生成默认构造方法,只能从字节码层面进行验证
使用Student类为例:

class Student{
    public String name;
    int age;
    //提供构造方法
    public Student(){
        System.out.println("我是构造方法!");
    }
    public Student(String name,int age){
        this.name = name;
        this.age = age;
        System.out.println("Person<String,int>");
    }
}

方法1 jclasslib插件

使用这个插件前,需先行安装:jclasslib插件的安装

显式定义构造方法

编译之后,构造方法的名字被修改为 < init >


上述有两个 < init > ,如何区分哪个构造方法有参?

任意打开一个 < init >,找到局部变量表

由上图,你会发现:局部变量表里,有一个参数 this,这个 this 就是我们对象的那块空间

构造方法是对 对象进行初始化,那么进行初始化的对象 和 对象空间的位置如何确定,就需要来传构造方法,故 我们看到构造方法没有参数时,却有一个隐藏的this,将对象的地址传进来了
注意: this 传的并不是真正的地址,而是对象的地址 转换后的内容

而另外有参数的构造方法的局部变量表:
你会发现,除了name,age外,也有 this

则可说明:
构造方法的名字替换成了相对应的 < init >


则上述过程也可以说明,如若没有显式定义构造方法:

  • ①.便可以在 jclasslib 里找是否存在 < init > 方法,若存在,即可说明编译器提供了默认的构造方法
  • ②.在 < init > 里找到局部变量表,查看除this外是否有其他参数,若没有,即可证明编译器提供的是没有参数的构造方法

按照上述方法验证:

即:一个类若没有显式定义构造方法,编译器会自动生成一个无参的默认构造方法
一旦用户显示定义,编译器就不再生成

方法2 javap 工具进行反汇编

未显式定义构造方法

class Student{
    public String name;
    int age;
}

public class Exercise0909 {
    public static void main(String[] args) {
        Student student = new Student();
    }
}

1.打开终端,找到对应目录,输入javap -c反汇编


2.观察反汇编结果


由反汇编结果可看出,未显式定义构造方法,编译器自动提供了一个构造方法

3.使用 javap -v

找到对应的局部变量表,看其中值得个数即可

局部变量表内:主要用来存储方法的参数 以及方法当中定义的局部变量
上述代码,未定义局部变量,则 局部变量表里 存放的便是 隐藏的this参数,用来存储对象地址转换后的内容

显式定义构造方法

class Student{
    public String name;
    int age;
    
    //提供构造方法
    public Student(String name,int age){
        this.name = name;
        this.age = age;
        System.out.println("Person<String,int>");
    }
}

和上述过程一样,这里不做过多赘述,直接截取核心代码验证:


可见,局部变量表里存放了3个参数,分别为 this,name,age

以上两种方法,更推荐使用 jclasslib 来验证,更加直观清楚!!

以上是关于怎么证明未显式定义构造方法时,编译器会自动生成无参的构造方法?的主要内容,如果未能解决你的问题,请参考以下文章

变量作用域构造方法。

C++——构造函数和析构函数

c++类的构造函数不显式声明会自动生成吗

c++类的构造函数不显式声明会自动生成吗

java:子类和父类之间的调用方法_构造方法

构造器及重载