Java 链接器如何工作?

发布于 2024-11-16 15:45:22 字数 195 浏览 3 评论 0原文

我想知道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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

无可置疑 2024-11-23 15:45:22

不存在 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.

愚人国度 2024-11-23 15:45:22

首先:方法始终是类的一部分。接口基本上只是特殊的类,而包只是类的完全限定名称的一部分,对类文件的可见性和物理组织有一些影响。

所以问题归结为:JVM 如何链接类文件?您链接到的 JVM 规范说:

Java 编程语言允许
实施灵活性
当链接活动时(并且,因为
递归、加载)发生,
前提是语义
语言受到尊重,班级
或接口已完全验证
并在初始化之前做好准备,
并且在期间检测到错误
链接被抛出在一个点
执行某些操作的程序
可能需要链接的程序
涉及到的类或接口
错误。

例如,一个实现可以
选择解决每个符号
类或接口中的引用
单独使用时,仅在使用时
(懒惰或迟解决),或
一次性解决所有问题,例如,
当班级正在验证时
(静态分辨率)。这意味着
解决过程可能会继续,
在一些实现中,在上课之后
或者接口已经初始化。

因此,这个问题只能针对特定的 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:

The Java programming language allows
an implementation flexibility as to
when linking activities (and, because
of recursion, loading) take place,
provided that the semantics of the
language are respected, that a class
or interface is completely verified
and prepared before it is initialized,
and that errors detected during
linkage are thrown at a point in the
program where some action is taken by
the program that might require linkage
to the class or interface involved in
the error.

For example, an implementation may
choose to resolve each symbolic
reference in a class or interface
individually, only when it is used
(lazy or late resolution), or to
resolve them all at once, for example,
while the class is being verified
(static resolution). This means that
the resolution process may continue,
in some implementations, after a class
or interface has been initialized.

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.

山田美奈子 2024-11-23 15:45:22

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.

毁梦 2024-11-23 15:45:22

如前所述,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:

Linking a class or interface involves verifying and preparing that
class or interface, its direct superclass, its direct superinterfaces,
and its element type (if it is an array type), if necessary.
Resolution of symbolic references in the class or interface is an
optional part of linking.

This specification allows an implementation flexibility as to when
linking activities (and, because of recursion, loading) take place,
provided that all of the following properties are maintained:

  • A class or interface is completely loaded before it is linked.

  • A class or interface is completely verified and prepared before it is
    initialized.

  • Errors detected during linkage are thrown at a point in the program
    where some action is taken by the program that might, directly or
    indirectly, require linkage to the class or interface involved in the
    error.

https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4

╰つ倒转 2024-11-23 15:45:22

链接是类加载器执行的三项活动之一。它包括验证、准备和(可选)解决。

验证:它确保.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文