JDK 17 和JDK 8 相比新特性

目录

一、JDK17的新特性有哪些 ?

二、新特性Java代码演示

1.Sealed classes

2.Pattern matching for instanceof

3 Records

4 Text blocks

5 Switch expressions

6 Strong encapsulation of JDK internals

7 Foreign function and memory API

8 Improved support for Unicode 13.0.0

9 Vector API (preview)

10 ZGC 改进

11 G1 改进

12 统一的 JVM 日志系统

13 可过滤的 JVM 日志

14 强化了java.net.URL 类的安全性


一、JDK17的新特性有哪些 ?

  1. Sealed classes:允许限制类的继承和实现,有助于保证 API 类不被未授权的修改或扩展。
  2. Pattern matching for instanceof:允许在switch语句中使用模式匹配来测试一个对象是否是某个类的实例,使得编写简洁易读的代码更加容易。
  3. Strong encapsulation of JDK internals:通过使外部代码无法访问 JDK 内部 API 来提高JDK的安全性和可维护性。
  4. Foreign function and memory API:提供了与非 Java 代码和内存交互的标准API,使得与本地库和系统集成更加容易。
  5. Improved support for Unicode 13.0.0:包括对 Unicode 13.0.0定义的新字符和属性的支持。
  6. Records:一种新的语言特性,用于定义轻量级、不可变的数据类,可以大大减少模板化代码的数量。
  7. Text blocks:允许在源代码中创建多行字符串,提高了代码的可读性。
  8. Switch expressions:允许在 switch 语句中使用表达式,而不仅仅是常量,使得编写简洁易读的代码更加容易。

除此之外,JDK 17还包括一些改进和优化,如:ZGC 改进,G1 改进,统一的 JVM 日志系统,可过滤的 JVM 日志,强化了java.net.URL 类的安全性等。

二、新特性Java代码演示

1.Sealed classes

JDK 17 引入了一种新的封闭类(sealed class)的概念。封闭类是一种限制继承的类,它只能被特定的子类继承。下面的代码演示了如何定义和使用封闭类:

public sealed class Shape permits Circle, Rectangle, Triangle {
    public abstract double area();
}

public final class Circle extends Shape {
    private final double radius;
    public Circle(double radius) { this.radius = radius; }
    public double area() { return Math.PI * radius * radius; }
}

public final class Rectangle extends Shape {
    private final double width, height;
    public Rectangle(double width, double height) {
        this.width = width;
        this.height = height;
    }
    public double area() { return width * height; }
}

public final class Triangle extends Shape {
    private final double base, height;
    public Triangle(double base, double height) {
        this.base = base;
        this.height = height;
    }
    public double area() { return 0.5 * base * height; }
}

public class ShapeExample {
    public static void main(String[] args) {
        Shape shape = new Circle(2.0);
        System.out.println(shape.area());
    }
}

    // ...```


2.Pattern matching for instanceof

首先定义一个 Shape 接口:

public interface Shape {
    double area();
}

//然后可以定义一个 Circle 类:
public class Circle implements Shape {
    private final double radius;

    public Circle(double radius) {
        this.radius = radius;
    }

    public double getRadius() {
        return radius;
    }

    @Override
    public double area() {
        return Math.PI * radius * radius;
    }
}



接下来使用 instanceof 进行模式匹配:

Shape shape = new Circle(5.0);
if (shape instanceof Circle c) {
    double radius = c.getRadius();
    System.out.println("The area of the circle is: " + c.area());
}

这里使用了 instanceof 进行模式匹配,并将匹配到的对象强制转换为 Circle 类型。

3 Records

首先定义一个 Record 类型:

public record Person(String name, int age) {
}

然后可以创建一个 Person 对象:

Person person = new Person("John Doe", 30);
System.out.println(person.name());
System.out.println(person.age());

4 Text blocks

使用 text blocks 可以更容易地创建包含多行文本的字符串。

例如,创建一个 HTML 页面:

String html = """
    <html>
        <body>
            <h1>Hello, world!</h1>
        </body>
    </html>
    """;

这里使用了三个双引号来定义多行文本字符串,使得代码更加易读。

5 Switch expressions

可以使用 switch 表达式,而不仅仅是常量,来更简洁地编写代码。

例如,计算一个整数的平方:

int num = 5;
int square = switch (num) {
    case 1, 2, 3 -> num;
    default -> num * num;
};
System.out.println(square);

这里使用了 switch 表达式,而不是 switch 语句,使得代码更加简洁。

6 Strong encapsulation of JDK internals

JDK 17 加强了对 JDK 内部 API 的封装,使得外部代码无法访问这些 API。例如,下面的代码演示了如何使用反射获取到 JDK 内部 API 的 Unsafe 类:

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public class UnsafeExample {
    public static void main(String[] args) throws Exception {
        Field field = Unsafe.class.getDeclaredField("theUnsafe");
        field.setAccessible(true);
        Unsafe unsafe = (Unsafe) field.get(null);
        System.out.println(unsafe);
    }
}

然而,在 JDK 17 中,访问这个类的方式被阻止了。如果你尝试在 JDK 17 中运行上面的代码,你将会得到一个 java.lang.NoSuchFieldException: theUnsafe 异常,因为 theUnsafe 字段现在已经被标记为不再公开。

7 Foreign function and memory API

Foreign function and memory API 是一种与非 Java 代码和内存交互的标准 API。例如,以下代码演示了如何使用 Foreign Memory Access API 从 C 语言中分配内存:

import jdk.incubator.foreign.MemorySegment;
import jdk.incubator.foreign.MemoryAddress;
import jdk.incubator.foreign.MemoryLayout;
import jdk.incubator.foreign.MemoryAccess;

public class MemorySegmentExample {
    public static void main(String[] args) {
        try (MemorySegment segment = MemorySegment.allocateNative(1024)) {
            MemoryAddress address = segment.baseAddress();
            MemoryLayout layout = MemoryLayout.ofValue(1);
            int value = 42;
            MemoryAccess.setInt(address, 0, value);
            int result = MemoryAccess.getInt(address, 0);
            System.out.println(result);
        }
    }
}

这里使用了 Foreign Memory Access API 分配了 1024 字节的内存,然后将一个整数写入该内存并读取该整数,最后输出结果。

除此之外,Foreign Linker API 也提供了一种使用本地库和系统集成的标准方法。

8 Improved support for Unicode 13.0.0

JDK 17 提供了对 Unicode 13.0.0 中定义的新字符和属性的支持。例如,以下代码演示了如何使用 Character 类的新方法 isEmoji 判断一个字符是否是表情符号:

char emoji = 0x1F600;
if (Character.isEmoji(emoji)) {
    System.out.println("This is an emoji!");
} else {
    System.out.println("This is not an emoji.");
}

这里使用了 isEmoji 方法来判断一个字符是否是表情符号,并根据结果输出相应的消息。

9 Vector API (preview)

Vector API 是 JDK 16 引入的一个预览特性,旨在提供一组用于高效处理向量(即多个数据元素)的 API,以利用现代硬件的 SIMD(Single Instruction Multiple Data)功能,提高 Java 应用程序的性能。

Vector API 的设计基于 Java 语言和 Java 虚拟机的现有基础,因此开发人员可以使用熟悉的 Java 语言和工具来编写和调试使用向量操作的代码,同时利用硬件的 SIMD 功能获得更高的性能。

Vector API 支持多种数据类型,包括整数、浮点数和布尔值,并提供了一组基本的向量操作,如加、减、乘、除等。此外,它还支持使用表达式的方式来描述向量操作,从而简化代码编写和优化过程。

需要注意的是,Vector API 目前仍处于预览状态,可能会在未来的版本中进行更改和调整。因此,在使用 Vector API 时,开发人员需要注意相应的限制和注意事项,并进行适当的测试和优化,以确保代码的正确性和性能。

import java.util.Arrays;
import jdk.incubator.vector.FloatVector;
import jdk.incubator.vector.VectorOperators;

public class VectorAdditionExample {
    public static void main(String[] args) {
        float[] a = {1.0f, 2.0f, 3.0f, 4.0f};
        float[] b = {5.0f, 6.0f, 7.0f, 8.0f};
        float[] result = new float[4];

        // 使用 Vector API 进行向量加法
        FloatVector va = FloatVector.fromArray(FloatVector.SPECIES_256, a, 0);
        FloatVector vb = FloatVector.fromArray(FloatVector.SPECIES_256, b, 0);
        FloatVector vc = va.add(vb);

        // 将结果写入数组
        vc.intoArray(result, 0);

        // 输出结果
        System.out.println(Arrays.toString(result));
    }
}

该示例中,首先创建了两个长度为 4 的浮点数数组 a 和 b,并创建了一个用于存储结果的数组 result。然后,使用 FloatVector.fromArray 方法将数组转换为 FloatVector,并使用 add 方法执行向量加法操作。最后,使用 intoArray 方法将结果写入数组 result 中,并输出结果。

需要注意的是,上述示例中使用的是 SPECIES_256,它表示使用 AVX(Advanced Vector Extensions)指令集。Vector API 支持多种不同的指令集,包括 SSE、AVX、AVX-512 等。在实际使用中,开发人员应该根据具体的硬件和需求选择适当的指令集

这些只是 JDK 17 中的一些新特性和改进,还有更多值得探索的特性和改进。

10 ZGC 改进

JDK 17 中对 ZGC(可伸缩的低延迟垃圾回收器)进行了一些改进,其中包括了针对 MappedByteBuffer 和堆外内存的改进,使得它们可以更快地进行垃圾回收,提高了应用程序的性能。

11 G1 改进

JDK 17 中对 G1(Garbage-First)垃圾回收器进行了一些改进,其中包括了针对大型堆的改进,以提高 G1 垃圾回收器的性能和可靠性。此外,还对 G1 进行了一些内存管理和优化,以提高垃圾回收的效率。

12 统一的 JVM 日志系统

JDK 17 中引入了一个统一的 JVM 日志系统,它可以在运行时收集并记录 JVM 和应用程序的日志信息,并支持按时间戳、等级和线程 ID 等进行筛选和过滤,以帮助开发人员更轻松地调试和分析应用程序的运行情况。

13 可过滤的 JVM 日志

JDK 17 中还增加了一些新的日志选项,使得开发人员可以更灵活地控制 JVM 的日志输出。其中包括了新的命令行选项和配置文件选项,以及一些用于控制日志输出格式和级别的 API。

14 强化了java.net.URL 类的安全性

JDK 17 中对 java.net.URL 类进行了一些改进,以增强其安全性。其中包括禁用了 java.net.URLClassLoader.newInstance(URL[]) 方法,以及限制了 java.net.URL 的默认协议处理器,以避免一些潜在的安全问题。此外,还提供了一些新的选项和 API,以帮助开发人员更好地控制和管理 java.net.URL 的使用。

<think>嗯,用户问的是JDK21相比JDK8有哪些新特性。首先,我需要回忆一下JDK8的主要特性,然后对比JDK21新增的内容。JDK8是在2014年发布的,带来了Lambda表达式、Stream API、方法引用、默认方法等重大改进。而JDK21是2023年发布的,作为长期支持版本,肯定有很多新特性。 接下来,我需要分清楚JDK8JDK21之间各个版本的变化,但用户只需要比较JDK21JDK8。可能用户是从JDK8升级到JDK21,想了解有哪些新功能或改进。需要列出JDK21的新特性,尤其是那些对开发有重大影响的特性。 首先想到的是虚拟线程,也就是Project Loom的一部分,这是JDK21的重要特性,可以显著提升并发性能。然后是分代ZGC,垃圾回收方面的改进,这对内存管理性能优化有帮助。还有模式匹配的增强,比如switch的模式匹配,这简化了代码结构。 还有结构化并发,这属于并发编程的改进,让多线程代码更易管理。还有记录类(Record Classes),虽然JDK14引入,但可能JDK8用户不熟悉,需要提到。还有密封类(Sealed Classes),限制类的继承,增强封装性。 字符串模板也是一个新特性,方便字符串拼接。还有向量API,属于性能优化,用于并行计算。另外,弃用移除的部分,比如移除了偏向锁,可能会影响一些应用的性能表现。 需要将这些特性分门别类,比如核心语言特性、并发改进、垃圾回收、API增强等。同时,要简要说明每个特性的作用优势,让用户明白升级后的好处。可能用户关心的是升级的必要性、兼容性以及如何利用新特性优化现有代码。 另外,要提醒用户升级时需要注意的变化,比如废弃的功能,可能导致的兼容性问题。例如,移除了某些过时的API,或者默认启用的新特性可能需要调整参数。 总结时,要强调JDK21在性能、开发效率可维护性方面的提升,以及作为LTS版本的支持周期,鼓励用户升级以获得更好的支持特性。</think>JDK 21(2023年发布)相比JDK 8(2014年发布)引入了大量改进新特性,以下是核心变化的分类总结: --- ### 一、核心语言特性升级 1. **虚拟线程(Virtual Threads)** - JDK 21通过Project Loom实现轻量级线程(协程),显著降低高并发场景下的资源消耗。 - 对比JDK 8的`Thread`类,虚拟线程通过`Executors.newVirtualThreadPerTaskExecutor()`创建,支持百万级线程并发。 2. **模式匹配增强** - **`switch`模式匹配**(JDK 17预览,JDK 21最终定型): ```java // JDK 21示例 Object obj = "Hello"; String result = switch (obj) { case Integer i -> "整数: " + i; case String s -> "字符串: " + s; default -> "未知类型"; }; ``` - **记录模式(Record Patterns)**:直接解构记录类的字段。 3. **记录类(Record Classes)**(JDK 16引入) - 简化不可变数据载体类的定义: ```java record Point(int x, int y) {} // 自动生成equals/hashCode/toString ``` 4. **密封类(Sealed Classes)**(JDK 17引入) - 限制类的继承关系,增强封装性: ```java public sealed interface Shape permits Circle, Square {} ``` --- ### 二、并发与性能改进 1. **结构化并发(Structured Concurrency)**(JDK 19预览,JDK 21最终定型) - 通过`StructuredTaskScope`管理多线程任务生命周期,避免线程泄漏。 2. **分代ZGC(Generational ZGC)** - 提升垃圾回收效率,将堆内存分为新生代老年代,降低停顿时间。 3. **向量API(Vector API)**(JDK 16预览,JDK 21优化) - 支持SIMD指令加速数值计算,适用于机器学习大数据场景。 --- ### 三、API增强 1. **字符串模板(String Templates)**(JDK 21预览) - 内嵌表达式简化字符串拼接: ```java String name = "Alice"; String info = STR."Hello \{name}!"; // 输出 "Hello Alice!" ``` 2. **`SequencedCollection`接口**(JDK 21新增) - 为集合类(如`LinkedHashMap`)提供统一的首尾元素访问方法: ```java SequencedCollection<String> list = new ArrayList<>(); list.addFirst("a"); // JDK 8需手动实现 ``` 3. **HTTP/2 Client标准化**(JDK 11引入,JDK 8仅支持HTTP/1.1) - 支持异步请求WebSocket: ```java HttpClient client = HttpClient.newHttpClient(); HttpRequest request = HttpRequest.newBuilder().uri(URI.create("https://example.com")).build(); client.sendAsync(request, BodyHandlers.ofString()); ``` --- ### 四、弃用与移除 1. **移除了偏向锁(Biased Locking)** - 因性能优化效果有限且增加复杂度,默认禁用偏向锁(可通过`-XX:+UseBiasedLocking`手动启用)。 2. **废弃`SecurityManager`**(JDK 17标记为废弃) - 因现代安全模型变化,逐步淘汰传统安全管理器。 --- ### 五、升级建议 1. **性能提升**:ZGC/Shenandoah垃圾回收器、虚拟线程显著优化高并发场景。 2. **开发效率**:记录类、模式匹配等语法糖简化代码量。 3. **长期支持**:JDK 21是LTS版本(支持至2031年),适合企业级应用。 若从JDK 8升级,需注意模块化系统(JDK 9引入)对类路径的影响,建议通过`jdeprscan`检测废弃API。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值