Java程序需先经javac编译为平台无关字节码(.class),再由JVM加载、链接、初始化并执行;编译与运行分属独立阶段,各有类路径、版本及错误约束。
Java 程序不是直接被 CPU 执行的,它必须先经过 javac 编译成字节码(.class 文件),再由 JVM 加载并解释/编译执行。
Java 源文件(.java)不能被操作系统直接运行。必须用 javac 将其翻译为 JVM 能识别的二进制字节码(.class)。
javac 不生成机器码,只生成平台无关的字节码;同一份 .class 可在 Windows、Linux、macOS 的任意兼容 JVM 上运行import java.util.List),javac 仅检查语法和符号存在性,不校验运行时行为-g 参数可保留,对排查 Exception 堆栈有用error: class XXX is public, should be declared in a file named XXX.java —— 公有类名必须与文件名完全一致(大小写敏感)运行阶段由 java 命令触发,背后是 JVM 完成类加载、验证、准备、解析、初始化五步,最终调用 main 方法。
public static void main(String[] args) 方法,且类名需与 .class 文件名一致(区分大小写)CLASSPATH 查找类;若类在包中(如 com.example.App),需确保目录结构匹配,并用完整类名启动:java com.example.App
Exception in thread "main" java.lang.NoClassDefFoundError: XXX,通常是类路径缺失、类名拼错、或静态初始化块抛异常导致类加载失败java -verbose:class 可观察哪些类被加载,适合排查类冲突或双亲委派问题不同 JDK 版本生成的字节码有主版本号(major version),高版本 JVM 可运行低版本字节码,但反过来会报错。
:javac -source 8 -target 8 Hello.java,避免在旧 JVM 上运行时报 UnsupportedClassVersionError
.class 文件版本:javap -verbose Hello.class | grep "major"
--enable-preview 相关特性需显式开启,否则即使编译通过,运行时也会抛 UnsupportedOperationException
JVM 启动后并非全程解释执行字节码。HotSpot VM 会在运行时识别热点方法,用 JIT(Just-In-Time)编译器将其编译为本地机器码,提升性能。
-XX:+PrintCompilation 查看哪些方法被 JIT 编译jaotc)在 JDK 16+ 已弃用,当前主流仍是 JIT真正容易被忽略的是:编译和运行是两个独立阶段,各自有独立的类路径、版本约束和错误模型。一次 javac 成功,不代表 java 一定能跑起来;而一个看似“运行成功”的程序,也可能因 JIT 未覆盖关键路径,在高并发下暴露出性能拐点。