我想知道Java链接器的工作原理。具体来说,它将类,接口,包,方法等组合成jvm可执行格式。我找到了一些信息here,但关于链接顺序的信息并不多。
答案 0 :(得分:13)
没有Java“链接器”这样的东西。然而,有一个类加载器的概念 - 给定一个来自“某处”的java字节代码数组 - 可以创建一个类的内部表示,然后可以与new
等一起使用。
在这种情况下,接口只是特殊类。加载类后,可以使用方法和字段。
答案 1 :(得分:11)
首先:方法始终是类的一部分。接口基本上只是特殊的类,而包只是类的完全限定名称的一部分,对可见性和类文件的物理组织有一些影响。
所以问题归结为:JVM如何链接类文件?您链接的JVM规范说:
Java编程语言允许 实施的灵活性 链接活动时(和,因为 递归,加载)发生, 前提是语义 语言受到尊重,即一类 或界面完全验证 并在初始化之前准备好, 并且在期间检测到错误 联系被扔在了一个点上 采取某些行动的计划 可能需要联系的程序 涉及的类或接口 错误。
例如,实现可以 选择解决每个符号 类或接口中的引用 个别地,仅在使用时 (懒惰或迟到的解决方案),或 例如,一次解决所有问题 正在验证课程 (静态分辨率)。这意味着 解决过程可能会继续, 在一些实现中,在课后 或界面已初始化。
因此,只能针对特定的JVM实现来回答问题。
此外,它应该永远不会对Java程序的行为产生影响,除非可能出现链接错误导致运行时Error
实例被抛出的确切点。
答案 2 :(得分:8)
Java没有按照C的方式进行链接。主要单位是类定义。很多类引用与其定义的匹配发生在运行时。因此,您可以针对一个版本的库编译一个类,但在运行时提供另一个版本。如果相关的签名匹配,一切都会好的。在编译时有一些常量的内在,但就是这样。
答案 3 :(得分:2)
如前所述,Java编译器没有链接器。但是,JVM有一个链接阶段,它在类加载后执行。 JVM规范最多定义它:
链接类或接口涉及验证和准备 类或接口,它的直接超类,它的直接超接口, 及其元素类型(如果是数组类型),如果需要的话。 类或接口中符号引用的解析是一个 链接的可选部分。
该规范允许实现灵活性 链接活动(并且,由于递归,加载)发生, 只要保留以下所有属性:
在链接之前,类或接口已完全加载。
类或接口在完成之前已经过完全验证和准备 初始化。
链接期间检测到的错误会抛出程序中的某个点 程序可能直接或采取某些行动的地方 间接地,需要链接到涉及的类或接口 错误。
https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html#jvms-5.4
答案 4 :(得分:0)
链接是ClassLoader执行的三个活动之一。它包括验证,准备和(可选)解决方案。
验证:它确保.class文件的正确性,即检查此文件是否由有效的编译器正确格式化和生成。如果验证失败,我们将获得运行时异常java.lang.VerifyError。
准备工作:JVM为类变量分配内存,并将内存初始化为默认值。
解决方案:这是用直接引用替换类型中的符号引用的过程。通过搜索方法区域以找到引用的实体来完成此操作。