Java添加package声明后运行报java.lang.NoClassDefFoundError问题咨询
核心原因
这是Java包命名规则和类加载机制共同作用的结果,核心逻辑如下:
- 当你在类顶部声明
package one;时,这个类的全限定类名就变成了one.Lec01,而不是简单的Lec01。Java虚拟机加载类时,会严格按照全限定类名去匹配对应的目录结构和class文件。 - 你在
src/one目录下直接运行java Lec01,JVM会默认从当前工作目录(也就是src/one)作为classpath根路径,去查找名为Lec01的无包类,自然找不到你编译出来的属于one包的Lec01.class——JVM找带one包的类时,会去classpath根路径下的one子目录里找,也就是它会尝试找src/one/one/Lec01.class这个不存在的路径,所以才会报NoClassDefFoundError: one/Lec01 (wrong name: Lec01)的错误,意思就是找到的class文件的类名和预期的全限定名不匹配。 - 你去掉
package one;之后,这个类就是无包类,全限定名就是Lec01,JVM在当前工作目录下直接就能找到匹配的Lec01.class,所以能正常运行。
带包声明时的正确运行方式
如果你要保留package one;声明,有两种正确的运行方法:
- 退到包的根目录执行
先切换到src目录(也就是one包的上级目录),再执行命令:
此时JVM以java one.Lec01src为classpath根路径,会去src/one目录下找Lec01.class,刚好匹配你编译出来的文件位置,就能正常运行。 - 编译时自动生成包目录结构
编译时加上-d参数指定输出根目录,javac会自动帮你生成对应包名的目录结构,比如你在src/one目录下执行:
会自动在当前目录下生成javac -d . Lec01.javaone子目录,把编译好的Lec01.class放在里面,之后你再在当前目录执行java one.Lec01也能正常运行。
内容的提问来源于stack exchange,提问作者Kushal Kumar
相关产品推荐
相关产品推荐

