为什么当有2个类型名称相似的对象时会出现ClassLoader异常

Why is there a ClassLoader exception when there are 2 objects with similar type names

我有一个 class 有 2 种方法。

这里是 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();
   
   }
   
}

这是我得到的异常。

Exception in thread "main" java.lang.NoClassDefFoundError: ClassLoaderIssueABC (wrong name: ClassLoaderIssueAbc)
    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

显然,这只是问题的一个可运行示例,但在我的情况下,让 local class/enum/record 处理域边缘的奇怪状态非常方便和有帮助。因此,我经常使用这种模式,但这是我第一次遇到这个问题。

显然,有很多方法可以解决这个问题。最简单的是我可以为一个枚举重命名。我已经尝试过并且有效。界面相同。

但是为什么会这样呢?

EDIT - 我还用 Java 18 测试了这个并得到了相同的结果。我使用了一个全新的文件,一个全新的文件夹,然后将文本(不是文件)复制并粘贴到一个同名的空文件中。同样的错误。我真的找不到比这更干净的测试了。

我刚刚编译了代码并 运行 它在我的机器上。它没有任何问题。

也许尝试删除所有现有 class 文件并重新编译所有内容。

否则你可以尝试不同的 java 版本,我过去也遇到过类似的问题。

在 Windows 上,文件名为 case-insensitive。这意味着无法区分名为 Something$ABC.class 和 Something$Abc.class 的文件。

同时,当然,语言本身是 case-sensitive,并期望文件名和文件中 class 的名称相匹配。

您唯一的办法似乎是重命名 class 或界面。