【发布时间】:2014-01-27 14:59:46
【问题描述】:
public class Config {
public static Ref<Config> s = new Ref<Config>(new Config());
static class Ref<T> {
public T r;
public Ref(T r) {
this.r = r;
}
}
public int INTERVAL = 4000;
public Config()
{
}
public static void main(String[] args) {
System.err.println(Config.s.r.INTERVAL);
}
}
将此原因运行到 java.lang.VerifyError
Exception in thread "main" java.lang.VerifyError: (class: Config, method: main signature: ([Ljava/lang/String;)V) Incompatible type for getting or setting field
如果我运行这个:
System.err.println(Config.s.r);
没有抛出异常,在调试中我可以看到'Config.s.r.INTERVAL'的值
当我使用 -verbose:class 运行时,我可以看到在第一个示例中没有加载 Ref 类。在第二个示例中,加载了 Ref 类。
这是项目中唯一使用java6编译和运行的类。 问题不在 jvm 或第 3 方。
我猜这个问题是在同一行结合静态变量初始化和实例变量。
像这样运行 - 工作:
Config c = Config.s.r;
System.err.println(c.INTERVAL);
附言。代码非常复杂,它在开发环境中分为 2 个类。我只是把它限制在简短的例子中
Jdk - Java SE 6 [1.6.0_65-b14-462] 操作系统 - Mac
【问题讨论】:
-
其中的原因都不属于这里。不涉及第三者。所有类都存在。
-
你确定它们都是用你运行的相同版本的 Java 编译的吗? Java 字节码承诺向前兼容,但不一定向后兼容(即,在 Java 1.7 上编译的代码可能无法在 Java 1.6 上运行)。验证错误意味着字节码中的某些内容未被您的 JVM 接受,唯一可能的原因是版本控制问题、JVM 错误或有人损坏了类文件。
-
我添加了 cmets。 10x
-
哇!!认为自己有幸找到了一种无需进行 .class 文件交换或类似操作即可引发 VerifyError 的方法!