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

0 阅读15分钟

"学长,面试官问JDK 8有什么新特性,我只能憋出个Lambda..."

"我刚入职,项目用的是JDK 17,看到代码里的varrecord一脸懵..."

"书上写的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,还给你配了编译工具、调试工具等,是咱们开发人员的全套装备。

1775736125402.png

为什么要了解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 平台一分为三:

平台全称用途
J2SEJava 2 Standard Edition标准版,桌面应用开发的地基
J2EEJava 2 Enterprise Edition企业版,服务器端、企业级应用的航空母舰
J2MEJava 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关键字:断言,用于调试

1775737845710.png

里程碑革命: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) 机制:

  1. 新特性先以预览版发布,让开发者试用
  2. 根据反馈决定是否保留或修改
  3. 预览特性默认禁用,需要加--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 有哪些核心新特性?

参考回答

  1. Lambda表达式:支持函数式编程,行为可以作为参数传递。
  2. Stream API:提供流式操作集合的方式,支持链式调用。
  3. 接口默认方法:接口可以包含带方法体的默认实现。
  4. 新的日期时间API:java.time包,替代DateCalendar
  5. Optional类:优雅地规避空指针异常。

为什么 JDK 8 这么重要,影响这么大?

参考回答: JDK 8是Java历史上最重要的版本,原因有三点:

  1. 语法革命:Lambda 和 Stream 改变了我们思考和编写代码的方式。
  2. 生态依赖:它统治了企业级应用开发超过十年,无数框架(如 Spring Boot 2.x)都基于它。
  3. 思维转变:推动 Java 从纯命令式编程向声明式、函数式编程演进。

一张表总结 Java 版本演进

阶段版本核心意义
诞生JDK 1.0跨平台理念,Applet时代
成长JDK 1.2-1.4集合框架、NIO、JIT编译器
革命JDK 5泛型、注解、for-each、自动装箱
企业JDK 6-7企业级特性,性能优化
现代JDK 8Lambda、Stream、函数式编程
模块化JDK 9-11模块系统、HttpClient、var
成熟JDK 12-17Switch表达式、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 的过程中还遇到过其他奇葩的版本问题,或者觉得文章有哪里讲得不对、不清楚的地方,欢迎在评论区留言交流! 你们的每一个问题,都是我下一篇笔记的灵感来源。如果觉得有用,也别忘了点个赞、收个藏,让更多的小伙伴看到。