Java 链接器如何工作?
我想知道Java链接器是如何工作的。具体来说,它按照什么顺序将类、接口、包、方法等组合成 jvm 可执行格式。我在这里找到了一些信息,但没有这样有关链接顺序的更多信息。
I want to know how Java linker works. Specifically, in which order it combines classes, interfaces, packages, methods and etc into jvm-executable format. I have found some information here, but there is not so much information about linking order.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
不存在 Java“链接器”这样的东西。然而,有一个类加载器的概念,它 - 给定来自“某处”的 java 字节代码数组 - 可以创建一个类的内部表示,然后可以与
new
等一起使用。场景接口只是特殊的类。加载类后,方法和字段就可用。
There is no such thing as a Java "linker". There is, however, the concept of a classloader which - given an array of java byte codes from "somewhere" - can create an internal representation of a Class which can then be used with
new
etc.In this scenario interfaces are just special classes. Methods and fields are available when the class has been loaded.
首先:方法始终是类的一部分。接口基本上只是特殊的类,而包只是类的完全限定名称的一部分,对类文件的可见性和物理组织有一些影响。
所以问题归结为:JVM 如何链接类文件?您链接到的 JVM 规范说:
因此,这个问题只能针对特定的 JVM 实现来回答。
此外,它不应该对 Java 程序的行为产生影响,除非链接错误导致运行时
Error
实例被抛出。First of all: methods are always part of a class. Interfaces are basically just special classes, and packages are just a part of the fully qualified name of a class with some impact on visibility and the physical organization of class files.
So the question comes down to: how does a JVM link class files? The JVM spec you linked to says:
Thus, the question can only be answered for a specific JVM implementation.
Furthermore, it should never make a difference in the behaviour of Java programs, except possibly for the exact point where linking errors result in runtime
Error
instances being thrown.Java 不像 C 那样进行链接。基本单位是类定义。类引用与其定义的许多匹配都发生在运行时。因此,您可以针对库的一个版本编译一个类,但在运行时提供另一个版本。如果相关签名匹配,一切就OK了。在编译时有一些常量内联,但仅此而已。
Java doesn't do linking the way C does. The principle unit is the class definition. A lot of the matching of a class reference to its definition happens at runtime. So you could compile a class against one version of a library, but provide another version at runtime. If the relevant signatures match, everything will be ok. There's some in-lining of constants at compile time, but that's about it.
如前所述,Java 编译器没有链接器。然而,JVM 有一个链接阶段,该阶段在类加载之后执行。 JVM 规范最多定义了它:
https://docs.oracle.com /javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4
As noted previously Java compiler doesn't have a linker. However, JVM has a linking phase, which performed after class loading. JVM spec defines it at best:
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4
链接是类加载器执行的三项活动之一。它包括验证、准备和(可选)解决。
验证:它确保.class文件的正确性,即检查该文件是否正确格式化并由有效的编译器生成。如果验证失败,我们会得到运行时异常 java.lang.VerifyError。
准备工作:JVM为类变量分配内存,并将内存初始化为默认值。
解决:这是用直接引用替换类型中的符号引用的过程。这是通过搜索方法区来定位引用的实体来完成的。
Linking is one of the three activities performed by ClassLoaders. It includes verification, preparation, and (optionally) resolution.
Verification : It ensures the correctness of .class file i.e. it check whether this file is properly formatted and generated by valid compiler or not. If verification fails, we get run-time exception java.lang.VerifyError.
Preparation : JVM allocates memory for class variables and initializing the memory to default values.
Resolution : It is the process of replacing symbolic references from the type with direct references. It is done by searching into method area to locate the referenced entity.