[英]Why is there a ClassLoader exception when there are 2 objects with similar type names
I have a class with 2 methods.我有一个 class 有两种方法。
In method1()
, I create a local record
called Abc
.在method1()
中,我创建了一个名为Abc
的local record
。 This local record
is only available to method1()
because it was defined in method1()
( here are the rules on it according to Java ).此local record
仅对method1()
可用,因为它是在method1()
中定义的( 这里是根据 Java 制定的规则)。
In method2()
, I create a local interface
called ABC
.在method2()
中,我创建了一个名为ABC
的local interface
。 Notice that there is a capitalization difference here.请注意,此处存在大小写差异。 The local record
was named Abc
, but this local interface
is named ABC
. local record
名为Abc
,但此local interface
名为ABC
。
Here is the class.这是 class。
//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();
}
}
And here is the Exception that I get.这是我得到的异常。
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)
And here is some relevant information.这是一些相关信息。
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
Obviously, this is just a runnable example of the problem, but I have a situation where it is extremely convenient and helpful to have local class/enum/record
to handle weird state at the very edges of my domain.显然,这只是问题的一个可运行示例,但我遇到的情况是让local class/enum/record
在我的域的边缘处理奇怪的 state 非常方便和有帮助。 Therefore, I use this pattern a lot, but this is the first time I have come across this issue.因此,我经常使用这种模式,但这是我第一次遇到这个问题。
Now obviously, there are many ways to go around this.现在显然,有很多方法可以解决这个问题 go。 The simplest being that I could just rename the enum for one.最简单的是我可以为一个枚举重命名。 I already tried that and that worked.我已经尝试过并且有效。 Same for the interface.界面也一样。
But why does this happen?但是为什么会这样呢?
EDIT - I also tested this with Java 18 and got the same result.编辑- 我还用 Java 18 测试了这个并得到了相同的结果。 I used a brand new file, a brand new folder, and I copied and pasted the text (not the file), into an empty file with the same name.我使用了一个全新的文件,一个全新的文件夹,然后将文本(不是文件)复制并粘贴到一个同名的空文件中。 Same error.同样的错误。 I can't really get a cleaner test than that.我真的找不到比这更干净的测试了。
On Windows, file names are case-insensitive.在 Windows 上,文件名不区分大小写。 This means that files called Something$ABC.class and Something$Abc.class cannot be distinguished.这意味着无法区分名为 Something$ABC.class 和 Something$Abc.class 的文件。
Meanwhile, of course, the language itself is case-sensitive, and expects the file name and the name of the class within the file to match.同时,当然,语言本身是区分大小写的,并且希望文件名和文件中的 class 的名称相匹配。
Your only recourse seems to be to rename either the class or the interface.您唯一的办法似乎是重命名 class 或界面。
I just compiled the code and ran it on my machine.我只是编译代码并在我的机器上运行它。 It works without any problems.它工作没有任何问题。
Maybe try to delete all existing class files and recompile everything.也许尝试删除所有现有的 class 文件并重新编译所有内容。
Otherwise you can try a different java version, I had similar problems related to that in the past.否则你可以尝试不同的 java 版本,我过去也遇到过类似的问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.