我有一个含有2个方法的类。
在
method1()
中,我创建了一个名为Abc
的local record
。这个local record
只能在method1()
中使用,因为它是在method1()
中被定义的(根据 Java 的规则,在此处可以查看有关此规则的详细信息)。在
method2()
中,我创建了一个名为ABC
的local interface
。请注意,这里有一个大小写不同之处。前面提到的local record
名称为Abc
,但是这个local interface
名称为ABC
。
以下是该类:
//package ..... //commenting out package information, as I sincerely doubt that is the cause
/** There seems to be a class loader error when running the below method in main(). */
public class ClassLoaderIssue
{
/** Method 1. */
private void method1()
{
record Abc(int a)
{
public static String iDontCare()
{
return "ignore this method";
}
}
System.out.println(Abc.iDontCare()); //error
}
/** Method 2. */
private void method2()
{
interface ABC
{
}
}
/**
*
* Main method.
*
* @param args commandline arguments that we don't care about for this example.
*
*/
public static void main(String[] args)
{
new ClassLoaderIssue().method1();
}
}
以下是我收到的异常信息。
Exception in thread "main" java.lang.NoClassDefFoundError: ClassLoaderIssue$1ABC (wrong name: ClassLoaderIssue$1Abc)
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
at ClassLoaderIssue.method1(ClassLoaderIssue.java:23)
at ClassLoaderIssue.main(ClassLoaderIssue.java:49)
以下是相关信息。
Java compile command = C:\Program Files\Java\jdk-17.0.2\bin\javac.exe
Java run command = C:\Program Files\Java\jdk-17.0.2\bin\java.exe
显然,这只是问题的一个可运行示例,但我遇到了一种情况,需要使用 本地类/枚举/记录
来处理域边缘的奇怪状态,这非常方便和有帮助。因此,我经常使用这个模式,但这是我第一次遇到这个问题。
现在显然,有很多方法可以解决这个问题。最简单的方法是我可以重新命名一个枚举值。我已经尝试过了,那样是行得通的。接口也是一样。
但为什么会发生这种情况呢?
编辑 - 我还测试了Java 18并得到了相同的结果。我使用了一个全新的文件夹和文件,并将文本(而不是文件)复制粘贴到同名的空文件中。仍然存在错误。我无法进行更干净的测试。
ABC
和Abc
类文件。更重要的是,这会影响可移植性,而解决方案非常简单(只需将$1
递增为$2
)。 - davidalayachewthis-escape
警告。一旦你这样做了,我在帖子中描述的问题将会引发一个警告。 - undefinedjavac -Xlint:all Abc.java
- undefined