Java类大小写引发NoClassDefFoundError问题求助(JDK17)
Java类名大小写引发NoClassDefFoundError的原因解析
你使用JDK17编写的第一段代码出现异常,核心原因是操作系统文件系统的大小写敏感性与Java类加载机制的冲突,具体拆解如下:
报错代码示例
class helloWorld { void p() { System.out.println("123123123"); } } public class HelloWorld { public static void main(String[] args) { helloWorld h = new helloWorld(); h.p(); } }
对应的报错信息
Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld (wrong name: helloWorld) 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 HelloWorld.main(HelloWorld.java:11)
正常运行的代码示例
class hello { void p() { System.out.println("123123123"); } } public class HelloWorld { public static void main(String[] args) { hello h = new hello(); h.p(); } }
问题根源说明
- Java的严格大小写规则:Java语言完全区分大小写,
helloWorld和HelloWorld是两个独立的类,编译后会生成helloWorld.class和HelloWorld.class两个字节码文件。 - 操作系统文件系统的特性:如果你的操作系统是Windows(或其他默认大小写不敏感的系统),文件系统会判定
helloWorld.class和HelloWorld.class为同一文件名。编译时,后生成的HelloWorld.class会直接覆盖先生成的helloWorld.class。 - 类加载时的匹配冲突:当JVM执行
main方法尝试加载helloWorld类时,找到的是被覆盖后的HelloWorld.class文件,但该文件内的实际类名是HelloWorld,与要加载的类名不匹配,因此抛出NoClassDefFoundError。 - 改名后正常的原因:将类名改为
hello后,编译生成的hello.class和HelloWorld.class在大小写不敏感的文件系统中会被识别为不同文件名(首字母h和H区分),不会发生覆盖,JVM能正确找到对应类文件完成加载,代码因此正常运行。
内容的提问来源于stack exchange,提问作者黄振宇
相关产品推荐
相关产品推荐

