java不同的版本对比

Java 8 相比 Java 7 是一次革命性的升级,它引入了函数式编程的思想。以下是 5 个最核心的新特性及代码对比,帮助你直观理解:

1. Lambda 表达式 (Lambda Expressions)

这是 Java 8 最具标志性的改动。它简化了匿名内部类的写法,使代码更简洁。

  • Java 7 (使用匿名内部类):
    new Thread(new Runnable() {
    @Override
    public void run() {
    System.out.println("Hello from Java 7");
    }
    }).start();
  • Java 8 (使用 Lambda):
    new Thread(() -> System.out.println("Hello from Java 8")).start();

2. Stream API

Stream API 极大地改变了处理集合(Collection)的方式,将以往繁琐的 for 循环和条件判断转化成了声明式的链式调用。

  • Java 7:
    List<String> names = Arrays.asList("Apple", "Banana", "Cherry");
    int count = 0;
    for (String name : names) {
    if (name.length() > 5) {
    count++;
    }
    }
  • Java 8:
    long count = names.stream().filter(name -> name.length() > 5).count();

3. Optional 类

为了解决令人头疼的 NullPointerException (NPE),Java 8 引入了 Optional 容器,强制开发者显式地处理空值。

  • Java 7:
    if (user != null && user.getAddress() != null) {
    String city = user.getAddress().getCity();
    }
  • Java 8:
    JavaString city = Optional.ofNullable(user)
    .map(User::getAddress)
    .map(Address::getCity)
    .orElse("Unknown");

4. 接口的默认方法 (Default Methods)

Java 8 允许在接口中通过 default 关键字编写具体的实现逻辑。这让接口在升级时不会破坏已有的实现类。

  • 代码示例:
    public interface MyInterface {
    void existingMethod();
    // Java 8 新增:即使不修改实现类,它们也自动拥有这个方法
    default void newDefaultMethod() {
    System.out.println("This is a default implementation.");
    }
    }

5. 新的时间日期 API (java.time)

Java 8 引入了全新的时间日期 API,解决了旧版 java.util.Date 线程不安全、设计混乱(如月份从 0 开始)等问题。

  • Java 7:
    Calendar cal = Calendar.getInstance();
    cal.set(2025, Calendar.DECEMBER, 31); // 极其啰嗦
    Date date = cal.getTime();
  • Java 8:
    LocalDate date = LocalDate.of(2025, 12, 31); // 直观、不可变且线程安全
    LocalDate tomorrow = date.plusDays(1);

从 Java 8 跨越到 Java 11(这期间经历了 Java 9 和 10),Java 经历了一次从“传统的单体 JDK”向“现代化、云原生友好型 JDK”的转型。

对于 Senior 职位,面试官最看重的是你对模块化、内存效率和 API 现代化的理解。


1. 局部变量类型推断 (var)

Java 10 引入了 var,在 Java 11 中得到了完善。它允许编译器推断局部变量的类型,减少冗余代码。

  • Java 8:JavaMap<String, List<User>> userGroups = new HashMap<>();
  • Java 11:Javavar userGroups = new HashMap<String, List<User>>(); // 代码更清爽,且依然保持了强类型检查

2. 全新的 HTTP Client (支持 HTTP/2)

Java 11 引入了标准的 java.net.http.HttpClient。相比 Java 8 那个极其难用的 HttpURLConnection,新 API 支持流式编程、异步请求以及 HTTP/2。

  • Java 11 代码示例:Javavar client = HttpClient.newHttpClient(); var request = HttpRequest.newBuilder() .uri(URI.create("https://api.example.com")) .GET() .build(); // 异步发送请求并处理响应 client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(HttpResponse::body) .thenAccept(System.out::println);

3. 模块化系统 (Project Jigsaw)

这是 Java 9 引入的最大改变。它允许你将应用程序拆分为多个 module,并显式声明依赖关系。

  • 影响: 你可以构建一个只包含必要组件的 定制版 JRE,这在 Docker 镜像部署时非常有用,能将镜像体积从几百 MB 缩小到几十 MB。
  • 封装性: 外部类不能再随意访问 sun.misc.* 等内部私有 API,增强了系统的安全性。

4. 字符串与集合 API 的小而美

Java 11 增加了一系列提升开发效率的“语法糖”:

  • String 增强:Java" ".isBlank(); // true "Hi\nHo".lines().count(); // 2 (流式处理行) "Java".repeat(3); // "JavaJavaJava"
  • 集合转数组:Java// Java 8 String[] array = list.toArray(new String[0]); // Java 11 String[] array = list.toArray(String[]::new);

5. JVM 的深层进化 (性能与容器)

这是 Senior 开发者必须掌握的底层差异

  • 默认垃圾回收器: Java 8 默认是 Parallel GC(追求吞吐量),Java 11 默认是 G1 GC(追求低延迟/平衡)。
  • 容器感知 (Container Awareness): Java 8 的早期版本在 Docker 中不知道自己受限,会疯狂申请内存导致 OOM。Java 11 原生支持识别 Docker 的内存和 CPU 限制。
  • 动态类文件常量 (Dynamic Class-File Constants): 降低了编译器设计者在实现新语言特性时的成本和开销。

针对 Java 11 到 Java 17 的跨越,这期间的变化主要集中在生产力提升(减少样板代码)数据建模能力以及类型系统的增强

作为 Senior 开发者,你需要掌握以下 5 个核心特性,它们彻底改变了 Java 代码的编写风格:


1. Records (记录类) —— 纯数据载体

这是 Java 17 最受欢迎的特性。它旨在消除 POJO/DTO 中冗长的 getterconstructorequalshashCode

  • Java 11: 必须手动编写或依赖 Lombok。
  • Java 17:
    // Java 17: 一行代码搞定构造函数、Getter、toString、equals 和 hashCode
    public record User(Long id, String name) {}
    /* * 注:Record 的字段默认为 private final。 * 它非常适合作为 SaaS 系统中那些“一旦创建就不应修改”的消息体或配置项。 */

2. Sealed Classes (密封类) —— 架构约束力

允许你精确限制哪些类可以继承或实现特定的类/接口。这在设计核心业务逻辑(如不同的营销任务类型)时非常有价值。

  • Java 17 代码证明:
    // 声明只有 EmailTask 和 SmsTask 可以继承
    Task public sealed class Task permits EmailTask, SmsTask {}
    public final class EmailTask extends Task {}
    public final class SmsTask extends Task {}

3. Switch 表达式 (Switch Expressions)

Switch 变强了:它可以作为表达式返回值,且不再需要写繁琐的 break

  • Java 11: 传统的 switch 容易因为漏写 break 导致 Fall-through Bug。
  • Java 17:
    String status = switch (statusCode) {
    case 200 -> “SUCCESS”;
    case 404, 500 -> “ERROR”;
    default -> {
    log.info(“Unexpected code”);
    yield “UNKNOWN”; // 使用 yield 返回复杂逻辑的值
    }
    };

4. 模式匹配 (Pattern Matching for instanceof)

类型检查和转换一步到位,消除了丑陋的强制类型转换。

  • Java 11:
    if (obj instanceof String) {
    String s = (String) obj; // 需要手动强转
    System.out.println(s.toLowerCase());
    }
  • Java 17:
    if (obj instanceof String s) { // 直接定义变量
    System.out.println(s.toLowerCase());
    }

5. 文本块 (Text Blocks)

对于需要处理 SQL、JSON 或 HTML 的开发者来说,这简直是救星。

  • Java 11: 需要不断使用 + 拼接字符串并处理手动换行。
  • Java 17:
    String query = """
    SELECT * FROM users WHERE status = 'ACTIVE' ORDER BY id DESC
    """;

从 Java 17 到 Java 21(2023年发布)的升级,被誉为 Java 近十年最重要的一次飞跃。如果说 Java 17 优化了代码的“长相”,那么 Java 21 则彻底优化了 Java 的“灵魂”——并发模型

作为 Senior 开发者,理解 Java 21 的虚拟线程是面试中的必杀技。


1. 虚拟线程 (Virtual Threads) —— 革命性变化

这是 Java 21 最核心的特性(Project Loom)。它解决了传统 Java 线程(平台线程)过于昂贵的问题。

  • 痛点: 传统的线程与 OS 线程 1:1 绑定,每个线程占用约 1MB 内存。如果你有 1000 个并发请求阻塞在 I/O 上,你的服务器内存就快爆了。
  • 突破: 虚拟线程由 JVM 管理,极度轻量(仅几 KB)。你可以轻松开启 100 万个 虚拟线程而不会宕机。
  • Java 21 代码示例:
// 为每个任务创建一个虚拟线程,不再需要复杂的线程池管理
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
    IntStream.range(0, 10_000).forEach(i -> {
        executor.submit(() -> {
            Thread.sleep(Duration.ofSeconds(1)); // 即使阻塞,也不会占用物理线程
            return i;
        });
    });
} // 自动等待所有任务完成

2. 顺序集合 (Sequenced Collections)

Java 终于统一了获取集合“第一个”和“最后一个”元素的方法。以前 ListDequeSet 各有各的搞法,现在整齐划一。

  • Java 21 代码示例:
var list = List.of("A", "B", "C");
list.getFirst(); // "A"
list.getLast();  // "C"
list.reversed(); // 返回逆序视图 [C, B, A]

3. Record 模式匹配 (Record Patterns)

在 Java 17 中你有了 Record,但在 Java 21 中,你可以直接在判断时“拆解”它。

  • Java 17: if (obj instanceof User u) { var name = u.name(); ... }
  • Java 21 (直接拆解):
if (obj instanceof User(String name, int age)) {
    System.out.println("User: " + name + " is " + age + " years old");
}

4. Switch 模式匹配 (Pattern Matching for switch)

Switch 现在可以处理任何类型,并且支持“守护条件”(Guards)。

  • Java 21 代码示例:
String description = switch (obj) {
    case Integer i -> "It is an integer";
    case String s when s.length() > 10 -> "It is a long string"; // 带有条件的匹配
    case String s -> "It is a short string";
    case null -> "It is null"; // 原生支持 null 检查,不再报 NPE
    default -> "Unknown type";
};
Scroll to Top