You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JDK17下javac与java命令执行差异的原因咨询

JDK 17中Java类运行差异问题解析

问题背景

我使用JDK 17,代码如下:

package myPackage;
 
public class myClass {
  
  public static void main(String[] args){
    System.out.println("test");
  }
  
}

执行场景1:报错

在IntelliJ终端执行命令:

javac MyClass.java
java MyClass

出现错误:

Error: Could not find or load main class MyClass
java.lang.NoClassDefFoundError: myPackage/myClass(wrong name: MyClass)

执行场景2:成功运行

在IntelliJ终端执行命令:

javac MyClass.java
java MyClass.java

程序正常输出,无报错。

补充:当前终端工作目录就是存放MyClass.java的目录,文件内明确声明了myPackage包。

原因说明

1. 第一种执行方式报错的核心原因

你的代码声明了myPackage包,Java规范要求:带包名的类,编译后的.class文件必须放在与包名对应的目录结构下(也就是要放在myPackage/子目录里),而且运行时必须从包结构的根目录启动,同时指定完整的类名(包名.类名)。

你直接在当前目录执行javac MyClass.java,编译出的MyClass.class会留在当前目录,没有自动生成myPackage子目录来存放它。这时候执行java MyClass,JVM会去找没有包名的MyClass类,但实际编译出来的类是属于myPackage的(完整类名是myPackage.myClass),自然找不到,所以报错提示类名不匹配。

正确的执行步骤应该是这样:

  • 先创建myPackage目录,把MyClass.java移进去
  • 回到myPackage的父目录,执行javac myPackage/MyClass.java
  • 再执行java myPackage.myClass

或者用javac的-d参数指定输出目录,自动生成包结构:

javac -d . MyClass.java
java myPackage.myClass

2. 第二种执行方式成功的原因

从JDK 11开始,Java支持直接运行源文件的特性(java <源文件名>.java)。这种模式下,JVM会自动完成编译、临时生成符合包结构的类文件、加载运行的全流程,运行完还会自动清理临时文件,不需要你手动维护目录结构或者输入完整类名,所以能直接正常运行。

内容的提问来源于stack exchange,提问作者Vats

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:12:43