在Java里程序是如何被编译和执行的_Java执行流程解析

发布时间 - 2026-01-29 00:00:00    点击率:
Java源代码通过javac编译为.class字节码文件,该过程不生成机器码、无需链接,故跨平台;需确保类名与文件名严格一致,依赖文件需手动指定或用-sourcepath,输出目录用-d控制。

Java源代码怎么变成.class文件

Java程序的编译由javac完成,它把.java文件翻译成JVM能识别的字节码(.class文件),不是直接转为机器码。这个过程不涉及链接或平台适配,所以编译结果是跨平台的。

常见错误:javac HelloWorld.java报错“找不到符号”,大概率是类名和文件名不一致——public class HelloWorld必须保存在HelloWorld.java中,大小写也必须完全匹配。

  • javac默认只编译指定文件,不会自动编译其依赖的其他.java文件;有依赖时得手动列全,或用-sourcepath指定源码路径
  • 编译输出目录可用-d控制,例如javac -d ./out src/HelloWorld.java,否则.class会生成在当前目录,容易混乱
  • Java 14+ 默认启用--enable-preview特性需显式加参数,否则新语法(如record)会编译失败

JVM如何加载并运行.class文件

执行阶段由java命令触发,它启动JVM,再由类加载器(ClassLoader)按需读取.class字节码,经过验证、准备、解析、初始化后进入运行时数据区。注意:这里不重新编译,也不检查源码是否存在。

典型问题:java HelloWorld报错Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld,往往不是没编译,而是类路径不对——JVM找不到HelloWorld.class,尤其当它在子目录或-d指定了输出目录时。

立即学习“Java免费学习笔记(深入)”;

  • 运行时必须用类名(不含.class后缀),且区分包结构;例如com.example.Hello要放在com/example/Hello.class路径下,并用java -cp . com.example.Hello
  • java默认只查当前目录和CLASSPATH环境变量,不自动包含./outsrc等目录
  • 如果类依赖第三方jar,必须用-cp

    --class-path显式引入,例如java -cp ".:lib/gson.jar" Main(Linux/macOS)或java -cp ".;lib/gson.jar" Main(Windows)

从字节码到机器指令发生了什么

JVM不直接执行字节码,而是通过解释器逐行翻译,或在热点代码处用JIT编译器(如HotSpot的C1/C2)编译为本地机器码。这个过程对开发者透明,但影响实际性能表现。

容易被忽略的一点:JIT优化基于运行时行为,所以同一段代码在不同负载、不同JVM参数下,执行效率可能差异很大。比如-XX:+TieredStopAtLevel=1会禁用C2编译,强制只用C1,适合调试但性能下降明显。

  • 可通过-XX:+PrintCompilation看到哪些方法被JIT编译了
  • -Xcomp强制所有方法首次执行就编译(跳过解释阶段),但启动更慢,且未必提升整体吞吐
  • Java 9+ 的jshell是独立于标准JVM流程的REPL环境,它内部仍走编译→字节码→JVM加载链路,只是隐藏了文件落地步骤

为什么修改.java后不重新运行就看不到效果

因为java命令只读.class,不关联源码。改完.java必须重新javac,否则运行的还是旧字节码。IDE通常自动做这一步,但命令行里极易遗漏。

另一个陷阱:有些构建工具(如Maven)默认使用target/classes里的字节码,而你手动javac生成在当前目录,导致mvn exec:java运行的是旧版本。

  • 确认正在运行的字节码来源:用java -verbose:class HelloWorld 2>&1 | grep HelloWorld看JVM实际加载的是哪个路径下的类
  • 清理残留.class最稳妥的方式是删掉整个输出目录(如rm -rf out/del /s/q out\),而不是只删某个文件
  • Java 11+ 的java HelloWorld.java(直接运行源文件)是特殊语法糖,底层仍会隐式调用javac并缓存字节码到临时目录,但仅限单文件且无依赖场景
字节码和JVM之间的衔接是静态的,但JIT和类加载时机是动态的;很多“运行结果不符预期”的问题,其实卡在编译路径、类路径、或JIT尚未介入的早期执行阶段。


# linux  # java  # js  # windows  # 字节  # 工具  # ssl  # mac  # ai  # macos  # 环境变量  # win  # 热点  # cos  # maven  # jvm  # class  # public  # Thread  # ide  # 加载  # 的是  # 找不到  # 报错  # 或用  # 源代码  # 译为  # 也不  # 放在  # 首次 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel如何实现用户角色和权限系统_Laravel角色权限管理机制  Swift中swift中的switch 语句  Java遍历集合的三种方式  Bootstrap CSS布局之列表  Laravel API资源类怎么用_Laravel API Resource数据转换  网站制作软件免费下载安装,有哪些免费下载的软件网站?  如何快速选择适合个人网站的云服务器配置?  Android自定义控件实现温度旋转按钮效果  奇安信“盘古石”团队突破 iOS 26.1 提权  美食网站链接制作教程视频,哪个教做美食的网站比较专业点?  如何撰写建站申请书?关键要点有哪些?  如何快速搭建高效香港服务器网站?  LinuxShell函数封装方法_脚本复用设计思路【教程】  如何获取上海专业网站定制建站电话?  Laravel如何发送邮件_Laravel Mailables构建与发送邮件的简明教程  Win11怎么设置虚拟桌面 Win11新建多桌面切换操作【技巧】  java获取注册ip实例  焦点电影公司作品,电影焦点结局是什么?  php485函数参数是什么意思_php485各参数详细说明【介绍】  阿里云高弹*务器配置方案|支持分布式架构与多节点部署  Laravel怎么多语言本地化设置_Laravel语言包翻译与Locale动态切换【手册】  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  Linux系统命令中screen命令详解  如何在 Pandas 中基于一列条件计算另一列的分组均值  如何用搬瓦工VPS快速搭建个人网站?  BootStrap整体框架之基础布局组件  5种Android数据存储方式汇总  如何做网站制作流程,*游戏网站怎么搭建?  Laravel怎么实现一对多关联查询_Laravel Eloquent模型关系定义与预加载【实战】  开心动漫网站制作软件下载,十分开心动画为何停播?  Laravel如何发送系统通知_Laravel Notifications实现多渠道消息通知  北京企业网站设计制作公司,北京铁路集团官方网站?  Python文件异常处理策略_健壮性说明【指导】  Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解  Laravel Livewire是什么_使用Laravel Livewire构建动态前端界面  Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程  详解Android中Activity的四大启动模式实验简述  瓜子二手车官方网站在线入口 瓜子二手车网页版官网通道入口  网站图片在线制作软件,怎么在图片上做链接?  黑客入侵网站服务器的常见手法有哪些?  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  PythonWeb开发入门教程_Flask快速构建Web应用  Laravel如何实现API速率限制?(Rate Limiting教程)  实例解析Array和String方法  JavaScript如何实现错误处理_try...catch如何捕获异常?  Laravel如何自定义错误页面(404, 500)?(代码示例)  公司网站制作需要多少钱,找人做公司网站需要多少钱?  儿童网站界面设计图片,中国少年儿童教育网站-怎么去注册?  如何快速上传自定义模板至建站之星?