家喻户晓,在java里是不能给构造函数写返回值的,如果在低版本的编译器定义一个结构器写上返回值可能会报错,高版本外面他就是一个一般的办法。
可是如果构造函数没有返回值,那么比方Test t = new Test()咱们new一个对象的时候是怎么赋值的呢?

构造函数有返回值吗

写一段代码测试一下:

public class Test {    public Test() {           }    public static void main(String[] args) {        Test t = new Test();    }}

反编译一下看看:

 Code:       0: new           #5 // class com/irving/utils/baidu/Test       3: dup       4: invokespecial #6 // Method "<init>":()V       7: astore_1       8: return

从反编译的后果看 4: invokespecial #7 // Method "init": ()V,调用构造函数,V代表void无返回值,那么init代表什么含意?

我在书里找到这样一段话:

在 Java 虚拟机层面上,Java 语言中的构造函数是以一个名为init的非凡实例初始化办法的模式呈现的,init这个办法名称是由编译器命名的,因为它并非一个非法的 Java 办法名字,不可能通过程序编码的形式实现。实例初始化办法只能在实例的初始化期间,通过 Java 虚拟机的 invokespecial 指令来调用, 只有在实例正在结构的时候,实例初始化办法才能够被调用拜访。

一个类或者接口最多能够蕴含不超过一个类或接口的初始化办法,类或者接口就是通过这个办法实现初始化的。这个办法是一个不蕴含参数的静态方法,名为clinit。这个名字也是由编译器命名的,因为它并非一个非法的 Java 办法名字,不可能通过程序编码的形式实现。类或接口的初始化办法由 Java 虚拟机本身隐式调用,没有任何虚拟机字节码指令能够调用这个办法,只有在类的初始化阶段中会被虚拟机本身调用。

init代表着虚拟机调用构造函数,当初状况很显著,构造函数返回类型是void,那么它到底是怎么赋值的呢?

赋值探索

咱们明确一点,办法的调用过程就是栈帧入栈和出栈的过程,栈帧随着办法的调用创立,办法完结销毁。栈帧的外部蕴含局部变量表、操作数栈、动静链接等。

局部变量表示意办法调用时候的参数传递,当一个实例办法被调用的时候,第0个局部变量存储了以后实例办法所在对象的援用(this),后续的其余参数传递至1到N的间断地位。

操作数栈用来筹备办法调用的参数和返回后果。

以下面测试代码的办法来看Test t = new Test() 的调用过程:

  1. new 创立Test对象,并将其援用值压入操作数栈顶
  2. dup 复制栈顶数值并将复制值压入栈顶
  3. invokespecial 应用dup复制的援用并用来初始化,此时栈顶应该只有new创立的原始援用
  4. astore_1 将new创立的援用存入局部变量表索引为1的地位
  5. return 办法失常返回

从这个过程咱们曾经看进去了,整个过程最初咱们最终拿到了new之后创立的对象援用,并且保留到局部变量表中,能够供咱们持续应用。

关注公众号:java宝典