热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何访问构造函数?

我一直不明白为什么我们能够从其他类调用一个类的构造函数。构造函数是一种方法,通常在尝试从类中调用方法时,我们必须将该方法设为静态,以便我们可以访问它MyClass

我一直不明白为什么我们能够从其他类调用一个类的构造函数。构造函数是一种方法,通常在尝试从类中调用方法时,我们必须将该方法设为静态,以便我们可以访问它

MyClass.method();

或者我们会创建该类的一个实例,然后调用该方法(现在显然这个方法会与这个问题的前提相矛盾)

MyClass myClass = new MyClass();
myClass.method();

但是在构造函数的情况下,我们两者都不做。Java 如何在不执行这些方法的情况下调用类的构造函数?我知道类的构造函数必须对您从中调用它的类可见,即如果您正在调用的类构造函数位于不同的包中,则必须导入该包。

那么,Java 如何处理调用构造函数,以便能够在不使用上述方法的情况下调用它们呢?

回答

类构造函数在 Java 语言和 Java 字节码中具有超出普通方法的特殊支持。特别是,它们获得特殊名称并使用不同的字节码指令调用(与正常方法调用看起来像的典型方法调用与运行时调度invokespecial相反invokevirtual)。

引用JVMS(JVM 规范)第 3.8 节:

Java 虚拟机类实例是使用 Java 虚拟机的新指令创建的。回想一下,在 Java 虚拟机级别,构造函数显示为具有编译器提供的名称 的方法。这种特殊命名的方法称为实例初始化方法(第 2.9 节)。一个给定的类可能存在多个实例初始化方法,对应多个构造函数。一旦创建了类实例并且其实例变量(包括类及其所有超类的实例变量)已初始化为其默认值,就会调用新类实例的实例初始化方法。例如:

Object create() {
return new Object();
}

编译为:

Method java.lang.Object create()
0 new #1 // Class java.lang.Object
3 dup
4 invokespecial #4 // Method java.lang.Object.()V
7 areturn

如您所见,用于生成此示例的参考编译器首先创建所讨论对象的未初始化实例,将其与任何构造函数参数(未显示)一起压入堆栈,并用于invokespecial调用适当的构造函数以进行初始化物体。在语言级别,Java 不会让您编写在调用构造函数之前公开完全未初始化的对象的代码,尽管您仍然可以泄漏部分构造的对象。

值得注意的是,有不安全的方法(字面意思是在一个名为Unsafe的隐藏类中)获取对在低级别初始化但从未调用其构造函数的对象的引用。这些在某种程度上违反了 Java 语言规范,只有在绝对需要时才应格外小心地使用。






推荐阅读
author-avatar
金健winner
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有