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或第三方。
我猜这个问题是在同一行静态变量初始化和实例变量中组合。
像这样跑 - 工作:
Config c = Config.s.r;
System.err.println(c.INTERVAL);
聚苯乙烯。代码非常复杂,在dev env中分为2个类。我只是将它限制为简短的例子
Jdk - Java SE 6 [1.6.0_65-b14-462] 操作系统 - Mac
答案 0 :(得分:1)
我想这是一个错误。 任何解决方法是拆分为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的bug。
答案 1 :(得分:0)
翻译:
public static void main(java.lang.String[]);
Code:
// Fetch static field s -- place is stack location 1
0: getstatic #22; //Field s:LRef;
// Fetch instance field r using stack 1 as base -- place in stack location 1
3: getfield #33; //Field Ref.r:Ljava/lang/Object;
// Peform checkcast on stack location 1 to assure it's a "Config" -- leave stack unchanged
6: checkcast #1; //class Config
// Store stack location 1 into local variable 1. Pop stack.
9: astore_1
// Fetch static field System.err -- place in stack location 1
10: getstatic #37; //Field java/lang/System.err:Ljava/io/PrintStream;
// Fetch local variable 1 -- place in stack location 2
13: aload_1
// Fetch instance field I using stack 2 as base -- place in stack location 2
14: getfield #27; //Field INTERVAL:I
// Invoke println, using stack 1 as base, stack 2 as parm -- stack becomes empty
17: invokevirtual #43; //Method java/io/PrintStream.println:(I)V
20: return
}
破碎的人:
public static void main(java.lang.String[]);
Code:
// Fetch static field System.err -- place is stack location 1
0: getstatic #33; //Field java/lang/System.err:Ljava/io/PrintStream;
// Fetch static field s -- place in stack location 2
3: getstatic #22; //Field s:LRef;
// Fetch instance field r using location 2 as base -- place in stack location 2
6: getfield #39; //Field Ref.r:Ljava/lang/Object;
// --- Note that the checkcast should be here ---
// Fetch instance field I using location 2 as base -- place in stack location 2
9: getfield #27; //Field INTERVAL:I
// Perform checkcast on location 2, to assure it's a "Config" (it isn't)
12: checkcast #1; //class Config
// Invoke println using location 1 as base, location 2 as parm.
15: invokevirtual #43; //Method java/io/PrintStream.println:(I)V
18: return
}