我在A级有以下方法。所有A,B,C类和主要类别来自' A'被调用的是在同一个jar中。
public class A {
private static void init() {
if (!init) {
synchronized (B.class) {
if (!init) {
map = C.creat();
init = true;
}
}
}
}
}
代码在Throwable
区块(第4行)投掷java.lang.NoClassDefFoundError
,synchronized
。
可能是因为所有类都在同一个jar中,没有机会在运行时找不到类。
我已经完成了Existing Question中的解决方案但无法找到解决方案。请帮忙。
B类中有静态初始化块和静态变量。
如果我使用static object/class A
同步代码而不是' B',则可以解决此问题。我很想知道为什么我会遇到异常以及如何使用B类修复它。
答案 0 :(得分:0)
如果你真的把那个代码编译成了JAR;并且JAR包含B.class;那么这不可能发生。
唯一的选择是:您使用的JAR已损坏;或者它不包含你认为它应该包含的内容。
因此:验证您的JAR。有些事情一定是错的。例如,使用jar tf jarfile.jar
列出完整内容;并检查B.class是否真的在。
答案 1 :(得分:0)
在启动Java App时,类加载器会加载类对象或元数据。
由于以下原因,上述代码最终可能会出现在java.lang.NoClassDefFoundError中。
1>上面的静态方法init是从类A中的静态块中调用的。可能会发生类B仍未在类A之前加载并且类加载器试图锁定类B的类对象(元数据)并且未能找到类的定义。
如果您在A.class上同步,它可以工作,因为类加载器具有它的类元引用
为了使用B.class类,你可能不得不懒惰地调用A类中的init方法,并允许类加载器加载类的元信息。请避免从任何静态初始化程序块调用A类中的init()方法。
答案 2 :(得分:0)
在使用B
之前,B.class
中有任何方法或变量引用了吗?如果没有,那么B
没有,重复,没有被初始化。对class
文字的引用不会触发类初始化。 “静态阻止”是一个不正确的术语。它是“静态初始化程序块”。哪个没跑。
使用final Object
或A
的{{1}}成员进行同步,而不是B
字面值。