Java 编译与运行
编译和运行 Java 代码是 Java 开发过程中最基础也是最核心的步骤。理解这些步骤对于执行你的程序并查看代码运行结果至关重要。本章将手把手带你了解如何将 Java 源代码编译成字节码,以及随后如何使用 Java 虚拟机 (JVM) 运行这些字节码。
1. 编译过程 (The Compilation Process)
编译是将人类可读的源代码(在我们的例子中是 Java 代码)翻译成机器可执行代码的过程。然而,Java 并不是直接编译成针对你当前操作系统的底层机器码。相反,它会编译成一种中间表示形式,称为字节码 (bytecode)。这种字节码与平台无关,这意味着它可以在任何安装了 Java 虚拟机 (JVM) 的系统上运行。
1.1 从源代码到字节码
Java 编译器 javac 负责完成这项翻译工作。以下是编译期间发生的具体步骤:
- 语法和语义分析: 编译器首先检查你的代码是否存在语法错误(例如,缺少分号、关键字拼写错误)和语义错误(例如,类型不匹配、使用了未声明的变量)。如果发现任何错误,编译过程就会停止,你需要先修复它们才能继续。
- 代码生成: 如果代码完全没有错误,编译器就会生成字节码。字节码由 JVM 能够理解和执行的一系列指令组成。
- 创建 Class 文件: 生成的字节码会被保存在一个
.class文件中。这个.class文件的名称与你 Java 源代码文件中定义的类名完全一致(例如,HelloWorld.java编译后会生成HelloWorld.class)。
代码示例:
假设你有一个名为 HelloWorld.java 的简单 Java 程序:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}要编译这段代码,你需要在终端或命令提示符中输入以下命令:
javac HelloWorld.java如果编译成功,你的 HelloWorld.java 文件所在的同一目录下将会生成一个 HelloWorld.class 文件。
1.2 处理编译错误
编译错误是日常开发中非常常见的一部分。Java 编译器会提供极其详细的错误提示信息,帮助你快速定位并修复代码中的问题。
示例:
假设你在 HelloWorld.java 程序中不小心把 System.out.println 拼写成了 System.out.prntln:
public class HelloWorld {
public static void main(String[] args) {
System.out.prntln("Hello, World!"); // 故意的拼写错误
}
}当你尝试编译这段代码时,你会得到类似下面的错误提示:
HelloWorld.java:3: error: cannot find symbol
System.out.prntln("Hello, World!");
^
symbol: method prntln(String)
location: variable out of class System
1 error这段报错信息清楚地告诉了你以下关键线索:
- 发生错误的文件名 (
HelloWorld.java) - 发生错误的具体行号 (
3) - 错误的描述说明 (
cannot find symbol,即找不到符号) - 无法找到的具体符号 (
method prntln(String),即找不到prntln这个方法) - 编译器寻找该符号的位置 (
variable out of class System)
只要仔细阅读报错信息,你就能迅速发现并纠正拼写错误。
2. 执行过程 (The Execution Process)
一旦你成功将 Java 代码编译成了字节码,下一步就是执行它。这时候,就轮到 Java 虚拟机 (JVM) 登场了。
2.1 JVM 的核心作用
JVM 是一个专门用于执行 Java 字节码的软件环境。它充当了你编译后的代码与底层操作系统之间的“中间人”。正是这个机制赋予了 Java 跨平台的能力——同一份字节码,可以在任何配备了兼容 JVM 的系统上运行。
执行期间会经历以下步骤:
- 加载 (Loading): JVM 将
.class文件加载到系统内存中。 - 字节码校验 (Bytecode Verification): JVM 严格检查字节码,确保它是合法的且没有违反任何系统安全限制。
- 解释执行 / 即时编译 (JIT Compilation): JVM 可以直接逐条解释执行字节码,或者使用 JIT (Just-In-Time) 编译器将字节码实时翻译成底层操作系统的原生机器码,以极大地提升执行速度。现代 JVM 主要依赖 JIT 编译技术。
- 执行 (Execution): JVM 执行字节码(或经过 JIT 编译的原生代码),精准完成你程序中指定的所有操作。
2.2 运行你的 Java 程序
要运行编译好的 Java 程序,你需要使用 java 命令,后面跟上包含 main 方法的类名(千万不要加 .class 扩展名)。
示例:
要运行我们之前创建的 HelloWorld.class 文件,请使用以下命令:
java HelloWorld这将执行 HelloWorld 类中的 main 方法,你应该能在控制台上看到成功打印出的 "Hello, World!"。
2.3 深入理解 main 方法
main 方法是你的 Java 程序的入口点。当你运行程序时,JVM 会主动去寻找具有这种特定签名的 main 方法:
public static void main(String[] args) {
// 你的代码写在这里
}public: main方法必须声明为public(公开的),这样 JVM 才有权限从外部访问并启动它。static: 必须声明为static(静态的),这样 JVM 就可以在不创建该类实例(对象)的情况下直接调用它。void: 表示main方法执行完毕后不返回任何结果值。String[] args:main方法接收一个字符串数组作为参数。这些参数是你运行程序时,可以通过命令行传递给程序的外部指令。我们将在后续模块中专门讲解命令行参数。
3. 处理运行时错误 (Runtime Errors)
运行时错误,通常被称为异常 (Exceptions),是在程序正在执行的过程中发生的错误。导致这类错误的原因有很多,比如输入了无效数据、尝试除以零,或者访问了不存在的数组元素。我们将在后续专门的模块中深入探讨异常处理机制。
示例代码:
public class Division {
public static void main(String[] args) {
int numerator = 10;
int denominator = 0;
int result = numerator / denominator; // 潜在的除以零错误
System.out.println("结果: " + result);
}
}如果你运行这段代码,程序会立刻抛出一个 ArithmeticException(算术异常),因为在数学法则中你不能除以零。此时,程序会异常终止,并在控制台上打印出错误堆栈信息。
4. 使用集成开发环境 (IDE)
虽然你可以纯靠命令行来编译和运行 Java 代码,但集成开发环境 (IDE) 能为你提供更便捷、功能更丰富的开发体验。像 IntelliJ IDEA、Eclipse 和 NetBeans 这样的 IDE 能够全自动处理编译和执行过程,并提供代码自动补全、强大的调试工具等实用功能。
4.1 在 IDE 中编译和运行
在 IDE 中操作的具体步骤因软件而异,但基本流程大同小异:
- 创建项目: 在 IDE 中新建一个 Java 项目。
- 编写代码: 在 IDE 的智能编辑器中敲入你的 Java 代码。
- 编译: 大多数 IDE 会在你输入代码或保存文件时进行自动编译。你也可以通过菜单或快捷键手动触发编译。
- 运行: 要运行程序,通常只需点击一个绿色的“运行 (Run)”按钮,或者按下一个快捷键。IDE 会在后台替你完成编译(如果需要的话),然后立刻执行它。
- 查看输出: 程序的运行结果会直接显示在 IDE 底部的控制台 (Console) 窗口中。