【Java面试题】Java中的“构造方法” 真的是 “方法” 吗?

0. 背景

最近,偶然在网上看到有人在问

“Java的构造方法到底有还是没有返回值?”

并在提问者还随着问题对网上自己已经搜索到的答案表示了不满:

“Java构造方法有人说有返回值,有人说没有,难道就没人真正能给出正确答案吗?”

问题见https://www.zhihu.com/question/335196523/answer/751020648

当我看到这个问题的时候,我首先的反应是“Java的构造方法是没有返回值的”,随后我也便在网上搜索了一番,发现确实是持有两种截然不同观点的人都大有人在。于是我便开始想,一个如此基本的问题,应该是大家早都“统一口径”了才对啊,毕竟Java已经是一个拥有24岁高龄的语言了。伴随着这种疑问,我开始了对这个问题的调研。

1. 调研

对于Java基础的问题,最好的方法当然还是去官方的资料中去寻找。于是找到了Java语言规范的文档(Java8版本)。在标砖的语言规范中找到了一些线索,如下:

  1. 8.2 Class Memebers章节中,规定了类的成员的来源继承自父类、继承自父接口、自身定义这3个来源,同时里面写到了这样的内容:

    Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
    构造方法,静态初始化器,对象初始化器,都不是类的成员,因此它们也不可以被子类继承。

  2. 8.8 Constructor Declarations 章节 中,关于构造方法的定义有以下说明:

    a constructor declaration looks just like a method declaration that has no result
    一个 constructor 的定义就像是一个没有返回值的 method 的定义。

emm… 在调研之后,恍然大悟,终于意识到了问题所在:

这完全是一个英文转中文的翻译问题。

从官方的文档中,我们能够发现,对于Java中的类成员是很明确的有三种:

  1. Filed:成员变量
  2. Method:普通方法
  3. Type:内部定义的其他类型,如内部接口、内部类等

Constructor 则是负责对一个对象进行初始化的,会在对象创建完成后由系统执行,它本身并不是类的成员,更不是一个“方法”,Constructor 的中文应该是构造器更合适。

构造方法是:Constructor,成员方法是:Method也就是说,它们两个是两个平等的概念,而不是包含的关系。

回过头来,既然Constructor 都不是个“方法”,那就没有返回值这个问题了?毕竟返回值是”方法“才有的特性。

所以,这个本质问题就是把Constructor翻译成 构造方法是不合适的。想来这个翻译应该是受到了C++的影响。

2. 虚拟机层面

上面分析了语言方面的原因,接下来稍微深入下,看下Java虚拟机层面ConstructorMethod的区别。

构造器在字节码层面,是对应于一个名字为 的代码块,由编译器去生成,会在对象创建完成后需要初始化的时候进行执行。

两者的执行在虚拟机层面也是有区分的,它们会使用不同的虚拟机指令来执行,对应的虚拟机指令:

  • Constructor:使用invokespecial 指令来执行
  • Method: 使用 invokevirtual 指令类执行

参考:https://www.zhihu.com/question/335196523/answer/751020648

坚持原创技术分享,您的支持将鼓励我继续创作!