Java版本那么多,JDK 8、11、17到底该用哪个?

Java版本那么多,JDK 8、11、17到底该用哪个?

“学长,面试官问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 list = new ArrayList<>();

list.add("hello");

String s = list.get(0); // 不需要强制转换

2. 增强for循环(for-each): 遍历集合从未如此优雅

// 之前

for (Iterator 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 list = new ArrayList();

// 现在:右边不用重复写类型

List 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() {

@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 filtered = new ArrayList<>();

for (String s : list) {

if (s.length() > 3) {

filtered.add(s.toUpperCase());

}

}

// 现在:链式调用,声明式处理

List 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 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 list = new ArrayList<>();

// JDK 10:var自动推断类型

var name = "Java";

var list = new ArrayList();

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 = "\n" +

" \n" +

"

Hello

\n" +

" \n" +

"";

// JDK 15+:文本块(优雅~~~)

String html = """

Hello

""";

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 的过程中还遇到过其他奇葩的版本问题,或者觉得文章有哪里讲得不对、不清楚的地方,欢迎在评论区留言交流! 你们的每一个问题,都是我下一篇笔记的灵感来源。如果觉得有用,也别忘了点个赞、收个藏,让更多的小伙伴看到。

相关推荐

反的成语

反的成语

📅 09-18 👁️ 7406
为什么都要无底洞孩子

为什么都要无底洞孩子

📅 02-05 👁️ 3838
庖怎么读

庖怎么读

📅 11-01 👁️ 558