gpt4 book ai didi

java - 如果缺少未使用的类,JVM 会抛出异常吗?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:12:48 26 4
gpt4 key购买 nike

考虑程序:

public class Test {

public static void main(String[] args) {
if (Arrays.asList(args).contains("--withFoo")) {
use(new Foo());
}
}

static void use(Foo foo) {
// do something with foo
}
}

如果程序在没有参数的情况下启动,运行时类路径中是否需要 Foo ?

研究

报告链接错误时,Java 语言规范相当模糊:

This specification allows an implementation flexibility as to when linking activities (and, because of recursion, loading) take place, provided that the semantics of the Java programming 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.

我的测试表明只有在我实际使用 Foo 时才会抛出 LinkageErrors:

$ rm Foo.class

$ java Test

$ java Test --withFoo

Exception in thread "main" java.lang.NoClassDefFoundError: Foo
at Test.main(Test.java:11)
Caused by: java.lang.ClassNotFoundException: Foo
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more

可以依赖这种行为吗?或者是否有链接未使用代码的主流 JVM?如果是这样,我如何隔离未使用的代码,以便仅在需要时链接它?

最佳答案

您只需对测试代码进行少量更改即可回答该问题。

将类型层次结构更改为

class Bar {}
class Foo extends Bar {}

和程序

public class Test {
public static void main(String[] args) {
if (Arrays.asList(args).contains("--withFoo")) {
use(new Foo());
}
}
static void use(Bar foo) {
// don't need actual code
}
}

现在,如果 Foo 不存在,即使在进入 main 方法(使用 HotSpot)之前,程序也会因错误而失败。原因是 validator 需要 Foo 的定义来检查将其传递给期望 Bar 的方法是否有效。

如果类型完全匹配或者目标类型是 java.lang.Object,那么 HotSpot 会走捷径,不加载类型,其中赋值总是有效的。这就是为什么当 Foo 不存在时您的原始代码不会提前抛出。

最重要的是,抛出错误的确切时间点取决于实现,例如可能取决于实际的 validator 实现。正如您已经引用的那样,可以保证的是,尝试执行需要链接的操作将抛出先前检测到的链接错误。但是您的程序完全有可能永远无法进行尝试。

关于java - 如果缺少未使用的类,JVM 会抛出异常吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41965457/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com