"学长,面试官问JDK 8有什么新特性,我只能憋出个
Lambda...""我刚入职,项目用的是JDK 17,看到代码里的
var、record一脸懵...""书上写的J2SE、J2EE,怎么现在都叫Java SE了?"
如果你也有这些困惑,那这篇文章就是为你准备的。
我用了一整天时间,把Java从1996年诞生到今天的发展历程彻底梳理了一遍。看完这篇,你不仅知道每个版本有哪些重要特性,还能明白"为什么企业都用JDK 8"、"新项目该选JDK 17还是JDK 21"这些实际问题。
先说说我的困惑
说实话,刚开始学Java时,看到"JDK 1.8"、"JDK 11"、"JDK 17"这些版本号就头疼。不是说学Java吗?怎么还有这么多版本?它们有什么区别?我该用哪个?
更让我崩溃的是,书上偶尔还会冒出“J2SE”、“J2EE”这种老古董词汇。后来怎么又变成“Java SE”、“Jakarta EE”了?还有人老说“JDK 和 JVM 的关系”……
后来我花了一整天时间查资料、画图,总算把这一团乱麻理清了。今天就把我的学习笔记分享出来,保证你看完这篇,以后再也不迷糊!
Java 家族图谱:JDK、JRE、JVM 到底谁是谁?
咱们先来玩个角色扮演,理清这些核心概念的关系。
- Java 语言:家族里的“老祖宗”,定下了家规(语法规则)。
- JVM(Java 虚拟机):家族里的“全能翻译官”,不管是跟 Windows 说英语,还是跟 Mac 说法语,他都能把老祖宗的话翻译得明明白白。
- JRE(Java 运行时环境):“翻译官单人套餐”,只有 JVM 和一些基础工具,够让程序跑起来。
- JDK(Java 开发工具包):“翻译官豪华全家桶”,除了 JRE,还给你配了编译工具、调试工具等,是咱们开发人员的全套装备。

为什么要了解Java历史?
很多初学者觉得"历史有什么用?会敲代码不就行了?"
错!大错特错!
举几个例子:
- 面试官问:"JDK 8有哪些新特性?"你不懂历史怎么回答?
- 项目要用JDK 17,看到Lambda表达式、Stream API一脸懵,因为不知道这些是JDK 8引入的
- 同事说"咱们用新版本的Switch表达式",你完全不知道人家在说啥
懂历史,才能看懂技术的演进逻辑,学新东西也更快!
从一杯咖啡到 Java 帝国
诞生记(1991 - 1996)
1991 年,Sun 公司的詹姆斯·高斯林(James Gosling)带领团队启动了一个叫“Green”的项目,目标是为未来的智能家电(比如微波炉)写一套通用控制系统。
团队给这门新语言起名 Oak(橡树),灵感来源于高斯林办公室窗外的树。可惜,这个名字被别人注册了。后来,大家想起常去喝咖啡的一家店叫“Java”,于是,这个既好听又有代表性的名字就诞生了。这也是为什么 Java 的 Logo 是一杯热气腾腾的咖啡。
1996 年:JDK 1.0 横空出世
1996 年 1 月 23 日,JDK 1.0 正式发布,一句口号响彻全球:
“Write Once, Run Anywhere”(一次编写,到处运行)
这在当时简直是黑科技!同一份代码,不用任何修改,就能在 Windows、Mac、Linux 上跑,全靠 JVM 这个“万能翻译官”。那时候,一个叫 Applet 的东西让 Java 火遍大江南北——因为它能让网页动起来!
核心特性:
- Java语言基础语法(类、接口、异常处理)
- 基础类库(java.lang、java.io、java.util)
- Applet(能在浏览器里运行的小程序,当时超火!)
- AWT(图形界面工具包)
- 多线程支持
- 垃圾回收(GC)
野蛮生长:JDK 1.x 系列的进化(1997 - 2002)
JDK 1.1(1997年):内功修炼
这个版本奠定了 Java 企业级应用的基石。最重要的更新就是 JDBC,它让 Java 连接数据库变得标准化,没有它,Java 想在企业后端当大哥?门儿都没有。
主要新特性:
- JDBC:数据库连接API,让Java能操作数据库
- 内部类:可以在类里面再定义类,这个设计后来超级常用
- RMI:远程方法调用,支持分布式计算
- JavaBeans:可重用组件模型
- 反射API:运行时获取类的信息
JDK 1.2(1998年):“Java 2”平台诞生
这是一个里程碑式的版本,Sun 公司正式将 Java 平台一分为三:
| 平台 | 全称 | 用途 |
|---|---|---|
| J2SE | Java 2 Standard Edition | 标准版,桌面应用开发的地基 |
| J2EE | Java 2 Enterprise Edition | 企业版,服务器端、企业级应用的航空母舰 |
| J2ME | Java 2 Micro Edition | 微型版,当年诺基亚、摩托罗拉手机上的游戏和应用 |
核心新特性:
- 集合框架:List、Set、Map登场!之前用的Vector、Hashtable终于有替代品了
- JIT编译器:即时编译,大幅提升性能(之前是纯解释执行,慢得一批)
- Swing:更漂亮的图形界面组件
小贴士:JDK 1.2引入了HotSpot虚拟机,后来成为Java性能优化的里程碑。
JDK 1.3(2000年)和JDK 1.4(2002年):稳步前行
这两个版本主要是优化和增强:
JDK 1.3:
- HotSpot JVM成为默认,性能大幅提升
- Java Sound API(音频处理)
- JNDI(目录服务访问)
JDK 1.4:
- NIO:New I/O,非阻塞I/O,高性能网络编程的基石!
- 正则表达式:java.util.regex包
- 日志API:java.util.logging
- assert关键字:断言,用于调试

里程碑革命:JDK 5 —— Java 语言的成人礼(2004 年)
如果说前面的版本是打基础,那 JDK 5 就是一次语言层面的核聚变。从它开始,Java 的命名规则也变了,不再叫“JDK 1.5”,而是直接叫“JDK 5”。
这个版本的新特性多到爆炸,我们用代码说话:
核心新特性一览
1. 泛型(Generics): 告别强制类型转换,拥抱安全
// 泛型前:类型不安全,需要强制转换
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0); // 需要强制转换,容易出错
// 泛型后:类型安全,代码更清晰
List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0); // 不需要强制转换
2. 增强for循环(for-each): 遍历集合从未如此优雅
// 之前
for (Iterator<String> i = list.iterator(); i.hasNext(); ) {
String s = i.next();
System.out.println(s);
}
// 现在
for (String s : list) {
System.out.println(s);
}
3. 自动装箱/拆箱: 基本类型和包装类无缝切换
// 自动装箱:int -> Integer
Integer num = 10; // 编译器自动转为 new Integer(10)
// 自动拆箱:Integer -> int
int n = num; // 编译器自动转为 num.intValue()
4. 枚举类型(Enum): 让常量定义更规范
// 之前:用常量
public static final int SPRING = 1;
public static final int SUMMER = 2;
// 现在:用枚举,更安全、更优雅
public enum Season {
SPRING, SUMMER, AUTUMN, WINTER
}
5. 注解(Annotations): 给代码打上标签,框架开发的利器
@Override // 标记重写方法
@Deprecated // 标记过时方法
6. 可变参数
// 可变参数:参数数量可变
public void print(String... args) {
for (String s : args) {
System.out.println(s);
}
}
print("a", "b", "c"); // 可以传任意个参数
7. 静态导入
import static java.lang.Math.PI;
import static java.lang.Math.sqrt;
// 直接使用,不用写Math.
double area = PI * r * r;
double d = sqrt(9);
8. 并发工具增强
JDK 5还带来了java.util.concurrent包,里面有:
- ThreadPoolExecutor(线程池)
- ConcurrentHashMap(并发Map)
- CountDownLatch、CyclicBarrier(线程同步工具)
记忆口诀:JDK 5新特性记不住?记住"泛强自枚注可静"(泛型、增强for、自动装箱、枚举、注解、可变参数、静态导入)
企业级时代:JDK 6-7,2006-2011
JDK 6(2006年):稳扎稳打
主要聚焦于性能优化和易用性:
- 脚本语言支持(JSR 223):可以在Java里调用JavaScript
- JDBC 4.0:自动加载驱动,更方便
- G1垃圾回收器(实验性)
- JAXB(XML绑定)
- Java Compiler API:可以编程方式调用编译器
JDK 7(2011年):承前启后
JDK 7 原计划有大动作(Lambda 表达式),但因 Sun 公司被 Oracle 收购而推迟。不过,它带来的几个小特性却非常实用:
1. try-with-resources(自动关闭资源): 妈妈再也不用担心我忘记关流了
// 之前:手动关闭,容易忘记
BufferedReader br = new BufferedReader(new FileReader("file.txt"));
try {
String line = br.readLine();
} finally {
br.close(); // 必须手动关闭
}
// 现在:自动关闭
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line = br.readLine();
} // 自动关闭,不用写finally
2. 字符串switch: 终于不用写一堆 if-else 了
// 之前:只能用int、enum做switch
// 现在:字符串也可以!
String day = "MONDAY";
switch (day) {
case "MONDAY":
System.out.println("周一");
break;
case "TUESDAY":
System.out.println("周二");
break;
}
3. 菱形操作符(Diamond Operator): 让代码更简洁
// 之前:泛型要写两边
List<String> list = new ArrayList<String>();
// 现在:右边不用重复写类型
List<String> list = new ArrayList<>();
4. 二进制字面量
int binary = 0b1010; // 二进制
int underscore = 1_000_000; // 数字可以用下划线分隔
改变一切的 JDK 8:函数式编程的春天(2014 年)
JDK 8是迄今为止影响最深远的版本,没有之一!哪怕你现在用的是JDK 17、JDK 21,你每天写的代码也处处是 JDK 8 的影子。它改变了我们写 Java 代码的思维方式。
1. Lambda表达式:函数式编程时代
让 Java 正式拥抱函数式编程,代码量大幅减少。
// 之前:匿名内部类,啰嗦
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("Hello");
}
};
// 现在:Lambda表达式,简洁
Runnable r = () -> System.out.println("Hello");
// 集合排序对比
list.sort(new Comparator<String>() {
@Override
public int compare(String a, String b) {
return a.compareTo(b);
}
});
// Lambda写法
list.sort((a, b) -> a.compareTo(b));
2. Stream API:集合处理的革命
操作集合就像写 SQL 查询语句一样,声明式、链式调用,爽到飞起。
// 之前:一步步处理
List<String> filtered = new ArrayList<>();
for (String s : list) {
if (s.length() > 3) {
filtered.add(s.toUpperCase());
}
}
// 现在:链式调用,声明式处理
List<String> filtered = list.stream()
.filter(s -> s.length() > 3) // 过滤
.map(String::toUpperCase) // 转换
.collect(Collectors.toList()); // 收集结果
3. 接口默认方法
接口里可以写带方法体的方法了!
public interface MyInterface {
// 普通抽象方法
void doSomething();
// 默认方法:有默认实现
default void doSomethingElse() {
System.out.println("默认实现");
}
}
4. 新的日期时间API
终于告别难用的Date和Calendar了!
// JDK 8之前:Date和Calendar难用死了
Date date = new Date();
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 7);
// JDK 8:新的日期时间API
LocalDate today = LocalDate.now();
LocalDate nextWeek = today.plusDays(7);
LocalDateTime now = LocalDateTime.now();
5. Optional类:减少空指针异常
优雅地解决空指针异常(NullPointerException),告别丑陋的 if (obj != null) 判断。
// JDK 8之前
String name = getName();
if (name != null) {
System.out.println(name.length());
}
// JDK 8之后:用Optional包装
Optional<String> name = Optional.ofNullable(getName());
name.ifPresent(n -> System.out.println(n.length()));
小贴士:JDK 8之所以这么重要,是因为Lambda、Stream、Optional这些特性改变了我们写Java的方式,让代码更简洁、更易读、更函数式。
模块化时代来临:JDK 9 到 JDK 11 的革新(2017 - 2018)
JDK 9(2017年):模块化系统(Project Jigsaw)
将庞大的 JDK 拆分成一个个模块,让 Java 应用可以按需打包,为云原生时代铺路。
// module-info.java
module com.example.mymodule {
requires java.base; // 依赖其他模块
exports com.example.mymodule.api; // 导出包
}
主要新特性:
- 模块化系统:把JDK拆成多个模块,可以按需引入
- JShell:交互式编程工具,不用写完整类就能执行代码
- 集合工厂方法:List.of()、Set.of()、Map.of()
- 私有接口方法:接口里可以有私有方法了
JDK 10(2018年):var局部变量类型推断
// 之前:类型写在前面
String name = "Java";
ArrayList<String> list = new ArrayList<>();
// JDK 10:var自动推断类型
var name = "Java";
var list = new ArrayList<String>();
JDK 11(2018年):第二个长期支持版(LTS)
继 JDK 8 之后第一个被企业大规模采用的 LTS 版本。带来了标准化的 HttpClient API 和实验性的低延迟垃圾回收器 ZGC。
主要特性:
- HttpClient API:终于有标准化的HTTP客户端了!
- 直接运行单文件:java Hello.java,不用先编译
- ZGC:低延迟垃圾回收器(实验性)
- 移除Java EE和CORBA模块:甩掉历史包袱
语法糖不断:JDK 12 到 JDK 17 的现代化(2019 - 2021)
预览特性机制
从JDK 12开始,Java引入了 预览特性(Preview Features) 机制:
- 新特性先以预览版发布,让开发者试用
- 根据反馈决定是否保留或修改
- 预览特性默认禁用,需要加--enable-preview参数
关键版本特性速览
JDK 12-13:新式 Switch 表达式
// JDK 13+:新的Switch表达式
int days = switch (month) {
case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31;
case APR, JUN, SEP, NOV -> 30;
case FEB -> {
if (isLeapYear) yield 29;
else yield 28;
}
};
JDK 13-15:Text Blocks(文本块)
// 之前:字符串拼接
String html = "<html>\n" +
" <body>\n" +
" <p>Hello</p>\n" +
" </body>\n" +
"</html>";
// JDK 15+:文本块(优雅~~~)
String html = """
<html>
<body>
<p>Hello</p>
</body>
</html>
""";
JDK 14-16:Records(记录类)
// 之前:写一个数据类要一大堆代码
public class Person {
private final String name;
private final int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// getter、equals、hashCode、toString...
}
// JDK 16+:用record一键生成
public record Person(String name, int age) {
}
JDK 15-17:Sealed Classes(密封类)
// 限制类的继承关系
public sealed class Shape permits Circle, Rectangle, Square {
}
public final class Circle extends Shape {
} // final:不能再继承
public sealed class Rectangle extends Shape {
} // sealed:可以继续被继承
public non-sealed class Square extends Shape {
} // non-sealed:随便继承
JDK 17(2021年):第三个 LTS 版本,现代 Java 新标配
现代Java的标配!Spring Boot 3.x要求JDK 17+。
正式发布的特性:
- Sealed Classes(密封类)
- Pattern Matching for instanceof
- 强力封装JDK内部API
- 移除Applet
虚拟线程震撼登场:JDK 18 到 JDK 21 的并发革命(2022 - 2023)
JDK 21(2023年):第四个 LTS 版本,并发编程新时代
JDK 21 的虚拟线程(Virtual Threads) 正式发布,这是一项颠覆性的技术。它可以让你在一个应用中轻松创建和管理上百万个并发线程,且几乎不消耗系统资源。
// 之前:传统线程,创建成本高
Thread thread = new Thread(() -> doWork());
thread.start();
// JDK 21+:虚拟线程,轻量级,可以创建百万个
Thread.startVirtualThread(() -> doWork());
// 或者用构建器
Thread virtualThread = Thread.ofVirtual()
.name("my-vt")
.start(() -> doWork());
一句话总结:高并发编程的门槛被 JDK 21 砸平了。
其他重要特性
- 结构化并发:更安全地管理并发任务
- String Templates(预览):更安全的字符串模板
- Sequenced Collections:统一的顺序集合接口
避坑指南
1. 版本号混淆
- “JDK 1.8” = “JDK 8” = “Java 8”,这是同一个东西的不同叫法。
- 别再说什么 J2SE 8 了,那个老黄历从 JDK 5 之后就翻篇了。
2. LTS 版本选择坑
- 千万别 看到新版本就无脑升到生产环境。
企业项目请认准 LTS 版本:
- JDK 8(已停止免费官方更新)
- JDK 11(支持至 2026 年)
- JDK 17(支持至 2029 年)
- JDK 21(支持至 2031 年,新项目强烈推荐)
Java SE 与 EE 混淆坑:
- Java SE 是地基,核心语法都在这。
- Java EE(现更名为 Jakarta EE)是建立在地基上的大楼,提供 Web 开发、企业服务等规范。
- 学 Java = 先学好 Java SE。
面试官最爱问的版本问题
JDK 8 有哪些核心新特性?
参考回答:
- Lambda表达式:支持函数式编程,行为可以作为参数传递。
- Stream API:提供流式操作集合的方式,支持链式调用。
- 接口默认方法:接口可以包含带方法体的默认实现。
- 新的日期时间API:
java.time包,替代Date和Calendar。 - Optional类:优雅地规避空指针异常。
为什么 JDK 8 这么重要,影响这么大?
参考回答:
JDK 8是Java历史上最重要的版本,原因有三点:
- 语法革命:Lambda 和 Stream 改变了我们思考和编写代码的方式。
- 生态依赖:它统治了企业级应用开发超过十年,无数框架(如 Spring Boot 2.x)都基于它。
- 思维转变:推动 Java 从纯命令式编程向声明式、函数式编程演进。
一张表总结 Java 版本演进
| 阶段 | 版本 | 核心意义 |
|---|---|---|
| 诞生 | JDK 1.0 | 跨平台理念,Applet时代 |
| 成长 | JDK 1.2-1.4 | 集合框架、NIO、JIT编译器 |
| 革命 | JDK 5 | 泛型、注解、for-each、自动装箱 |
| 企业 | JDK 6-7 | 企业级特性,性能优化 |
| 现代 | JDK 8 | Lambda、Stream、函数式编程 |
| 模块化 | JDK 9-11 | 模块系统、HttpClient、var |
| 成熟 | JDK 12-17 | Switch表达式、Records、密封类 |
| 并发 | JDK 18-21 | 虚拟线程、结构化并发 |
一句话概括:Java从1996年走到今天,每个版本都在进步,JDK 8是转折点,JDK 21是新高点,学Java不懂历史,就像看剧不从头看一样,总会缺了点什么。
与君共勉
好了,Java 这 30 年的家族史咱们今天就盘到这里。从 1996 年的青涩诞生,到 JDK 8 的如日中天,再到 JDK 21 的自我革新,Java 始终在解决开发者痛点的路上不断进化。
有人说技术迭代太快,学了也用不上。但我觉得,了解历史不是为了背版本号、记特性列表,而是为了理解技术的演进逻辑——每一个新特性的出现,都是为了解决过去某个让人抓狂的难题。
Java能走过30年,靠的不是追风口、炒概念,而是一步一个脚印地解决实际问题:
- 觉得代码啰嗦?引入泛型、for-each
- 觉得并发难写?引入线程池、并发集合
- 觉得函数式编程优雅?引入Lambda、Stream
- 觉得高并发有瓶颈?引入虚拟线程
学Java也是一样,不是为了学而学,而是为了解决问题。
希望这篇文章能帮你理清 Java 版本的脉络,以后无论是面试还是做技术选型,心里都能更有底气。
如果你在学 Java 的过程中还遇到过其他奇葩的版本问题,或者觉得文章有哪里讲得不对、不清楚的地方,欢迎在评论区留言交流! 你们的每一个问题,都是我下一篇笔记的灵感来源。如果觉得有用,也别忘了点个赞、收个藏,让更多的小伙伴看到。