主题
界面
主题
这是整个知识库的第一节课。目标不是学会写 Java,而是把"能编译、能运行、版本可控"这件事一次性做对。
环境问题是最容易劝退初学者的一类问题:'java' 不是内部或外部命令、版本不匹配、class file version 错误,这些报错会让人误以为自己不适合学编程。实际上它们和编程能力毫无关系,只是环境没配好。本节把这些问题一次讲清。
完成本节后,你应该能够:
java -version 的输出,说出当前用的是哪个版本、哪个发行版;本节无前置知识,只需确认三件事:
本机现状提示
本机已安装 OpenJDK 25.0.2 LTS(Microsoft 发行版),JAVA_HOME 指向 C:\Program Files\Microsoft\jdk-25.0.2.10-hotspot。
本知识库的教学基线是 Java 21 LTS:所有示例代码按 21 编写,用本机 JDK 25 通过 --release 21 编译即可兼容。也就是说——你现在不需要卸载或更换 JDK,本节的重点是理解版本体系与验证方法。
设想三个真实场景:
场景一:你照着教程敲完代码,命令行输入 java HelloWorld,得到 'java' 不是内部或外部命令。这不是代码问题,是系统根本不知道 java 在哪。
场景二:同事说"这个项目要用 JDK 17 跑",你装了最新版 Java 25,结果启动报错 UnsupportedClassVersionError。原因是编译用的版本比运行环境的新。
场景三:面试官问"JDK 和 JRE 有什么区别"。你以为这是背概念,其实它决定了你能不能解释"为什么 Java 程序换台机器还能跑"。
这三个场景的共同点是:版本和环境是工程的组成部分,不是安装软件的琐事。
JDK(Java Development Kit,开发工具包)
├── 编译器 javac、打包工具 jar、诊断工具 jcmd/jstack ...
└── JRE(Java Runtime Environment,运行环境)
├── 类库(String、List、Stream 等标准库)
└── JVM(Java Virtual Machine,虚拟机)
└── 真正执行字节码的程序一句话记忆:JDK ⊃ JRE ⊃ JVM。
.class 文件),屏蔽操作系统差异,"一次编写,到处运行"靠它实现;HelloWorld.java ──javac 编译──▶ HelloWorld.class ──java 运行──▶ JVM 执行
(源码) (字节码) (输出结果)关键点:编译一次,到处运行。.class 文件是平台无关的字节码,JVM 才是平台相关的。
Java 的版本号在历史上换过一次规则,这是最容易搞混的地方:
| 俗称 | 正式版本号 | 发布时间 | 状态 |
|---|---|---|---|
| Java 8 | 1.8 | 2014 | 存量项目仍大量使用,面试常考 |
| Java 11 | 11 | 2018 | LTS |
| Java 17 | 17 | 2021 | LTS,Spring Boot 3 的最低要求 |
| Java 21 | 21 | 2023 | LTS,本知识库基线 |
| Java 25 | 25 | 2025 | LTS,本机已安装 |
LTS(Long Term Support,长期支持版) 指官方提供多年安全更新的版本。企业选型几乎只在 LTS 里挑,所以不要用非 LTS 版本(如 Java 22、23)作为项目主版本。
为什么基线选 21 而不是最新版
Java 25 太新,企业采用率低、生态尚未完全跟上。教学基线选 21,理由有三:企业当前主流 LTS、Spring Boot 3.x 要求 17+、包含 Record / Sealed / 虚拟线程等现代特性。Java 8 的差异会在 S1 的《Java 版本特性》里单独对照。
Java 是开放标准,多家厂商都提供实现,常见的有:
| 发行版 | 提供方 | 特点 |
|---|---|---|
| Oracle JDK | Oracle | 商业使用需注意授权条款 |
| OpenJDK | 开源社区 | 参考实现,完全免费 |
| Temurin | Eclipse 基金会 | 免费,企业常用 |
| Microsoft OpenJDK | 微软 | 本机装的就是这个,Windows 上体验好 |
学习阶段用任意一个都行,它们都实现了同一套规范。真正要统一的是版本号,不是发行版。
打开 PowerShell,依次执行:
java -version
javac -version
echo $env:JAVA_HOME三条命令的含义分别是:运行的 Java 版本、编译器版本、JDK 安装目录。
.msi;多版本共存
同一台机器可以装多个 JDK。切换方式有两种:改 JAVA_HOME 指向的目录,或在 IDE 里为每个项目单独指定 SDK(推荐,《IDEA 与项目创建》 会讲)。不要为了"版本干净"反复卸载重装。
文件:labs/first-step/HelloFirstDay.java(独立示例文件,无 package 声明,不属于任何 Maven 模块) Java 版本:21 依赖:无(JDK 自带) 运行命令(在仓库根目录执行):
cd labs\first-step
javac --release 21 HelloFirstDay.java
java HelloFirstDay也可以不手动编译、一步运行:java HelloFirstDay.java(JDK 11+ 单文件源码模式;在 labs\first-step 目录内执行)。
public class HelloFirstDay {
public static void main(String[] args) {
System.out.println("Hello, Java 学习知识库");
System.out.println("JVM 版本: " + System.getProperty("java.version"));
System.out.println("JVM 供应商: " + System.getProperty("java.vendor"));
System.out.println("操作系统: " + System.getProperty("os.name"));
}
}预期输出(本机 JDK 25 的实际输出):
Hello, Java 学习知识库
JVM 版本: 25.0.2
JVM 供应商: Microsoft
操作系统: Windows 11--release 21 让编译器按 Java 21 的语言规则和类库生成字节码,同时阻止你无意中使用 22 以后才有的 API。这样代码在 JDK 21 和 JDK 25 上都能跑,是保证"示例代码跨版本一致"的标准做法。
环境类问题用不到断点,但要看懂输出:
java -version 输出的第一行 openjdk version "25.0.2" 中的 25.0.2 是版本号;build 25.0.2+10-LTS 里的 LTS 标记说明这是长期支持版;echo $env:JAVA_HOME 输出为空,说明环境变量没配,命令行找不到 JDK;'java' 不是内部或外部命令 原因:PATH 里没有 Java 的 bin 目录,或终端没重启。
修复:确认 JAVA_HOME 已设置,并把 %JAVA_HOME%\bin 加入 PATH,然后关闭并重开终端。
UnsupportedClassVersionError: class file version 69.0 原因:用高版本 JDK 编译,用低版本 JVM 运行(69 = Java 25,61 = Java 17,65 = Java 21)。
修复:编译时加 --release 21,或统一编译与运行的 JDK。
错误: 找不到或无法加载主类 HelloFirstDay 四种常见原因,按顺序排查:
.class 所在目录;public 类名与文件名一致);package 声明,却用简单类名运行。特征:报错末尾会多一行 原因: java.lang.NoClassDefFoundError: ... (wrong name: ...)。修复:把工作目录切到包根目录后用全限定类名运行(例如 labs/start 模块里的类要写 java cn.kb.learn.Main),或改用单文件源码模式 java Xxx.java 一步运行。目标:验证本机 Java 环境,并产出一份个人环境记录。
步骤:
java -version、javac -version、echo $env:JAVA_HOME,把三条输出原样记录;labs/first-step/HelloFirstDay.java(也可以把它复制到任意目录,再编译运行一次);HelloFirstDay.class 删掉,重新编译一次,确认能复现;验收方式:能把三条命令的输出和程序运行结果贴出来,并说清每条输出的含义。
扩展任务:故意把 PATH 里的 Java 路径删掉,观察报错,再改回来。亲手制造并修复一次,比看十遍文档管用。
基础题
.java 源码。(对 / 错)代码阅读题
public class VersionCheck {
public static void main(String[] args) {
System.out.println(System.getProperty("java.version"));
System.out.println(System.getProperty("java.home"));
}
}java.home 不等于 JAVA_HOME?编程题
Runtime.getRuntime().maxMemory(),单位是字节,请换算成 MB)。综合任务
--release、安装第二个 JDK、IDE 项目级 SDK 三选一),并写下一句话说明你选了哪种方案、为什么。提示 1(方向):第 5 题的"主版本号"可以从 java.version 字符串里截取,也可以用 Runtime.version().feature()。
提示 2(关键点):第 5 题的字节转 MB 用 maxMemory / 1024 / 1024;注意整数除法会截断小数,想保留一位小数可以用 double。
提示 3(接近答案):第 6 题最省事的方案是不装新 JDK,直接用 javac --release 21;这也是本知识库全部示例采用的方式。
javac 编译器,编译需要 JDK。java.version:当前运行程序的 JVM 版本号,如 25.0.2;java.home:当前 JVM 自己的安装目录,是运行时的真实路径;JAVA_HOME 是给人看的配置变量,实际运行时可以由 IDE、构建工具或启动脚本临时指定另一个 JDK。以 java.home 为准。public class VersionInfo {
public static void main(String[] args) {
String version = System.getProperty("java.version");
int feature = Runtime.version().feature();
long maxMemoryMb = Runtime.getRuntime().maxMemory() / 1024 / 1024;
System.out.println("版本号: " + version);
System.out.println("主版本: " + feature);
System.out.println("JVM 最大可用内存: " + maxMemoryMb + " MB");
}
}预期输出示例:
版本号: 25.0.2
主版本: 25
JVM 最大可用内存: 3966 MB说明:maxMemory 的值取决于机器内存与 JVM 参数,不同机器不同,这是正常的。
推荐答案:不安装第二个 JDK,统一用 javac --release 21。
javac --release 21 HelloFirstDay.java
java HelloFirstDay理由:本知识库所有示例都声明了目标版本 21,用 --release 可以保证语法与类库都不越界,同时不必维护多套 JDK 环境。当后续需要构建 Maven 项目时,统一在 pom.xml 里配置 <maven.compiler.release>21</maven.compiler.release>。
进入 《IDEA 与项目创建》 之前,请确认你能做到:
javac --release 21 编译并运行一个类;'java' 不是内部或外部命令 时知道先检查什么。《IDEA 与项目创建》 会把命令行操作搬进 IDE:创建 Maven 项目、运行、调试。本节是"能跑起来",《IDEA 与项目创建》 是"能高效地跑起来"。
无,可直接开始