0. 背景
最近,偶然在网上看到有人在问
“Java的构造方法到底有还是没有返回值?”
并在提问者还随着问题对网上自己已经搜索到的答案表示了不满:
“Java构造方法有人说有返回值,有人说没有,难道就没人真正能给出正确答案吗?”
问题见https://www.zhihu.com/question/335196523/answer/751020648
当我看到这个问题的时候,我首先的反应是“Java的构造方法是没有返回值的”,随后我也便在网上搜索了一番,发现确实是持有两种截然不同观点的人都大有人在。于是我便开始想,一个如此基本的问题,应该是大家早都“统一口径”了才对啊,毕竟Java已经是一个拥有24岁高龄的语言了。伴随着这种疑问,我开始了对这个问题的调研。
1. 调研
对于Java基础的问题,最好的方法当然还是去官方的资料中去寻找。于是找到了Java语言规范的文档(Java8版本)。在标砖的语言规范中找到了一些线索,如下:
在 8.2 Class Memebers章节中,规定了类的成员的来源继承自父类、继承自父接口、自身定义这3个来源,同时里面写到了这样的内容:
Constructors, static initializers, and instance initializers are not members and therefore are not inherited.
构造方法,静态初始化器,对象初始化器,都不是类的成员,因此它们也不可以被子类继承。在 8.8 Constructor Declarations 章节 中,关于构造方法的定义有以下说明:
a constructor declaration looks just like a method declaration that has no result
一个 constructor 的定义就像是一个没有返回值的 method 的定义。
emm… 在调研之后,恍然大悟,终于意识到了问题所在:
这完全是一个英文转中文的翻译问题。
从官方的文档中,我们能够发现,对于Java中的类成员是很明确的有三种:
- Filed:成员变量
- Method:普通方法
- Type:内部定义的其他类型,如内部接口、内部类等
而 Constructor 则是负责对一个对象进行初始化的,会在对象创建完成后由系统执行,它本身并不是类的成员,更不是一个“方法”,Constructor 的中文应该是构造器更合适。
构造方法是:Constructor,成员方法是:Method也就是说,它们两个是两个平等的概念,而不是包含的关系。
回过头来,既然Constructor 都不是个“方法”,那就没有返回值这个问题了?毕竟返回值是”方法“才有的特性。
所以,这个本质问题就是把Constructor翻译成 构造方法是不合适的。想来这个翻译应该是受到了C++的影响。
2. 虚拟机层面
上面分析了语言方面的原因,接下来稍微深入下,看下Java虚拟机层面Constructor和 Method的区别。
构造器在字节码层面,是对应于一个名字为
两者的执行在虚拟机层面也是有区分的,它们会使用不同的虚拟机指令来执行,对应的虚拟机指令:
- Constructor:使用invokespecial 指令来执行
- Method: 使用 invokevirtual 指令类执行
参考:https://www.zhihu.com/question/335196523/answer/751020648