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
最佳答案
我想这是一个错误。 任何解决方法都是拆分为 2 行,如下所示:
Config c = Config.s.r;
System.err.println(c.INTERVAL);
程序集之间的差异(差异仅在主函数中): 工作的,打破 2 行:
public static void main(java.lang.String[]);
Code:
0: getstatic #22; //Field s:LRef;
3: getfield #33; //Field Ref.r:Ljava/lang/Object;
6: checkcast #1; //class Config
9: astore_1
10: getstatic #37; //Field java/lang/System.err:Ljava/io/PrintStream;
13: aload_1
14: getfield #27; //Field INTERVAL:I
17: invokevirtual #43; //Method java/io/PrintStream.println:(I)V
20: return
}
破损的 - 全部在一行中:
public static void main(java.lang.String[]);
Code:
0: getstatic #33; //Field java/lang/System.err:Ljava/io/PrintStream;
3: getstatic #22; //Field s:LRef;
6: getfield #39; //Field Ref.r:Ljava/lang/Object;
9: getfield #27; //Field INTERVAL:I
12: checkcast #1; //class Config
15: invokevirtual #43; //Method java/io/PrintStream.println:(I)V
18: return
}
在@Hot Licks 的帮助下,问题出在损坏版本的 checkcast 中,它检查字段 (int) 而不是类。向 Oracle 打开错误。
关于java.lang.VerifyError - 当类的静态变量包含对类实例的引用时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21384076/