Java 16Java 17(LTS版本)新特性概述

news2024/12/27 11:35:35

一、Java 16

发布于2021年3月16日。Java 16主要特性有:

  • JEP 338:Vector API (Incubator) 向量 API(第一轮孵化)

  • JEP 387:Elastic Metaspace 弹性元空间

  • JEP 389:Foreign Linker API (Incubator) 外部链接器API (第一轮孵化)

  • JEP 393:Foreign-Memory Access API (Third Incubator)外部内存访问 API(第三轮孵化)

  • JEP 394:Pattern Matching for instanceof instanceof的模式匹配(转正)

  • JEP 395:Records Records(转正)

  • JEP 397:Sealed Classes (Second Preview) 封闭类(第二次预览)

更多内容请读者自行阅读:OpenJDK Java 16官方文档

1.1 JEP 338:向量API(第一轮孵化)

现代计算中,数据密集型操作非常常见,例如科学计算、机器学习和图形处理等,这些可以通过向量化来加速(同时对多个数据执行相同操作),但是,Java缺乏这种向量计算能力。

所以在Java 16引入向量API,旨在解决这些问题,通过提供一种机制,使得在 Java 中编写复杂的矢量算法成为可能,利用 HotSpot 对矢量化的现有支持,但采用一种使矢量化更加可预测和稳健的用户模型。手动编写的矢量循环可以表达高性能算法(例如矢量化的 hashCode 或专门的数组比较),这些算法可能是自动矢量化器无法优化的。

举个例子:

//简单标量计算
void scalarComputation(float[] a,float[] b,float[] c) {
    for (int i = 0; i < a.length; i++) {
        c[i] = (a[i]*a[i]*b[i]*b[i]) * -1.0f;
    }
}
​
//与上述等效的向量计算
void vectorComputation(float[] a,float[] b,float[] c) {
    int i =0;
    VectorSpecies<Float> species = FloatVector.SPECIES_PREFERRED;
    int upper = species.loopBound(a.length);
    for(;i<upper;i+=species.length()){
        var va=FloatVector.fromArray(species,a,i);
        var vb=FloatVector.fromArray(species,b,i);
        var vc=va.mul(va)
                .add(vb.mul(vb))
                .neg();
        vc.intoArray(c,i);
    }
}

ps:由于一直处于孵化阶段,所以不排除会有重大变化,进入预览阶段再详细介绍。

1.2 JEP 387:弹性元空间

自Java 8引入元空间以来,它一直因对外内存使用率过高而颇具争议,原因是很容易以错误的方式触发元空间分配器,从而导致过多的内存浪费。

此特性将元空间内存按较小的块分配,并将未使用的元空间内存返回给操作系统来提高弹性,从而提高应用程序性能并降低内存占用。

1.3 JEP 389:外部链接器API(第一轮孵化)

该特性是基于外部内存访问API基础上建立起来的,旨在提供纯Java访问原生代码的API,该API将大大简化绑定原生库原本复杂且容易出错的过程。

1.4 JEP 393:外部内存访问API(第三轮孵化)

  • 外部内存访问 API 最初由 JEP 370 提出,并于 2019 年底作为孵化 API 针对 Java 14。

  • 后来由 JEP 383 重新孵化,集成与Java 15中。

  • Java 16建议继续孵化。

1.5 JEP 394:instanceof模式匹配(转正)

  • instanceof 的模式匹配由 JEP 305 提出,并在 JDK 14 中作为预览功能提供。

  • 它由 JEP 375 重新提出,并在 JDK 15 中提供,用于第二轮预览。

  • 在Java 16成为正式特性。

摘自Java 14的例子:

public static void main(String[] args) {
    Object obj = new Object();
    if(obj instanceof String){
        //强转为String
        String str = (String) obj;
        String trim = str.trim();
    }
    //Java 14
    if(obj instanceof String str){
        //不必强转,直接使用
        String trim = str.trim();
    }
}

1.6 JEP 395:Records(转正)

  • Records由 JEP 359 提出,并在 JDK 14 中作为预览功能提供。

  • JEP 384 对设计进行了细微改进,并在 JDK 15 中作为预览功能第二次提供。

  • 在Java 16成为正式特性。

Record类型允许在代码中使用紧凑的语法形式来声明类,而且这些类能够作为不可变数据类型的封装持有者。

以下内容摘自Java14对Records的介绍:

Java 14以预览功能的形式引入了一个新特性:Records,主要目的是提供一种简洁的语法来声明类似数据的小型不可变对象,用于解决长期以来Java中定义纯数据载体类带来的繁琐问题。

Java语言架构师Brian Goetz曾经写过一篇文章(http://cr.openjdk.java.net/~briangoetz/amber/datum.html )提到:开发人员想要创建纯数据甾体类通常必须编写大量低价值、重复的、容易出错的代码,比如构造函数、getter/setter、equal()、hashCode()等方法。以至于很多人选择使用IDE的功能自动生成这些方法,还有一些会选择使用一些第三方类库,比如Lombok:

那么纯数据载体指的是什么呢,举个例子:

public class Student {
    private String name;
    private int age;
​
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
​
    public Student() {}
    //省略getter/setter()、toString()、hashCode()等方法
}

我们再看看Records的写法:

public record Student1(String name, int age) {
}
​
//使用
public static void main(String[] args) {
    Student1 student=new Student1("张三",12);
    int age = student.age();
    String name = student.name();
}

反编译一下:

public final class Student1 extends Record {
    private final String name;
    private final int age;
    public Student1(String string, int n) {
        this.name = string;
        this.age = n;
    }
    @Override
    public final String toString() {
        return ObjectMethods.bootstrap("toString", new MethodHandle[]{Student1.class, "name;age", "name", "age"}, this);
    }
    @Override
    public final int hashCode() {
        return (int)ObjectMethods.bootstrap("hashCode", new MethodHandle[]{Student1.class, "name;age", "name", "age"}, this);
    }
    @Override
    public final boolean equals(Object object) {
        return (boolean)ObjectMethods.bootstrap("equals", new MethodHandle[]{Student1.class, "name;age", "name", "age"}, this, object);
    }
    public String name() {return this.name;}
    public int age() { return this.age;}
}

通过反编译得到的类(妥妥的是一个语法糖啊),我们可以看到:

  • 生成了一个final修饰的Student1类,说明这个类不能有子类了。

  • 类中有两个private final修饰的属性,所以record中的属性都是private final修饰的。

  • 一个构造函数、两个getter方法还有hashCode()、toString()、equals()都是自动生成的。

还能干啥?前面的例子中我们创建了一个record,感觉空荡荡的,还能有其它成员变量和方法吗?当然能:

public record Student1(String name, int age) {
    //只能添加静态字段
    static int x;
    //静态方法
    public static void doSomething() {
        x++;
    }
    //实例方法
    public String getInfo(){
        return "姓名:"+name+",年龄:"+age;
    }
    //构造函数
    public Student1{
        if(age>=35){
            throw new IllegalArgumentException("年龄过大!!!");
        }
    }
}

就介绍这么多吧,总结一下它的优缺点:

  • 优点:record非常适合作为再各层间传递数据载体,比如DTO;且它是不可变的,这也说明可以确保线程安全。

  • 缺点:由于是不可变的,所以没有setter方法,通用性比较弱;且如果参数过多,写起来和看起来都不如传统的写法。

1.3 JEP 397:封闭类(二次预览)

封闭类由Java 15作为预览功能引入的,主要目的是为了限制类的继承情况,Java 16第二次预览,仅做了细微改动。

以下内容摘自Java 15对封闭类的介绍:

Java 15之前,Java认为"代码重用"始终是一个终极目标,所以一个类或接口都可以被任意的类继承或实现。

但是在很多场景中,这样做反而容易造成错误,比如某些公司只要具有985或211学历的人;那么在Java中创建Company抽象类时,应该只允许Work985和Work211类去扩展它。

通过这种方式,我们希望确保在域内不会出现误用Worker抽象类的情况,为了解决类似问题,Java 15引入了封闭类:

  • 封闭类用sealed修饰,它的所有子类都必须在同一个模块或包内。

  • 封闭类使用permits来指定允许继承的子类。

  • 封闭类的子类可以被声明为non-sealed或final。non-sealed可以被继承,final则不能。

//密封类
//接口写法
public sealed interface Company permits Worker985,Worker211 {
}
//抽象类写法
public abstract sealed class Company1 permits Worker985,Worker211 {
}
​
//子类
public final class Worker985 implements Company {
}
//非密封子类
public non-sealed class Worker211 implements Company {
}

二、Java 17(LTS版本)

Java 17于2021年9月14日发布,是一个LTS版本,共有14个特性,本节将精选以下几个特性介绍:

  • JEP 356:Enhanced Pseudo-Random Number Generators 增强的伪随机数生成器

  • JEP 406:Pattern Matching for switch (Preview) switch的模式匹配(一次预览)

  • JEP 409:Sealed Classes 封闭类(转正)

  • JEP 412:Foreign Function & Memory API (Incubator) 外部函数和内存 API (第一轮孵化)

  • JEP 414:Vector API (Second Incubator) 向量API(第二轮孵化)

更多内容请读者自行阅读:OpenJDK Java 17官方文档

2.1 JEP 356:伪随机数生成器增强

在Java 17之前,Java主要依赖java.util.Random和其子类来生成伪随机数:

  • Random:最基本的随机数生成器,线程同余(LCG)算法,效率不高,线程不安全。

  • ThreadLocalRandom:解决Random线程不安全的问题,同样是LCG算法,效率不高。

  • SecureRandom:生成的随机数具有高安全性,使用了更加复杂和不可预测的算法。

这些生成器在某些场景下不够高效且功能性不够多,针对这些问题,Java 17为随机数提供了一个全新的接口RanmdomGenerator,它的子类有:

  • Streamablegenerator:可以产生随机数流的生成器。

  • JumpableGenerator:可以“跳跃”到其序列中一个远端点的随机数生成器。

  • LeapableGenerator:类似于JumpableGenerator,但提供了更精细的控制。

  • ArbitrarilyJumpableGenerator:可以跳到其序列中任意点的生成器。

  • SplittableGenertor:可以分裂成两个或多个独立运行的随即谁生成器。

举个例子:

public static void main(String[] args) {
    //指定生成器的算法,默认是L32X64MixRandom
    RandomGenerator randomGenerator = RandomGenerator.of("L64X128MixRandom");
    randomGenerator.ints().limit(10).forEach(System.out::println);
}

下面是Java 17提供的11个伪随机算法:

2.2 JEP 406:Switch模式匹配(一次预览)

Java 17引入了模式匹配,增强了Switch的类型检查,允许case标签中不仅带有变量,还能带有模式匹配。

在Java 17之前,我们可能需要使用多个if-else来判断对象的类型,比如:

public static void main(String[] args) {
    Object obj = new Object();
    if(obj instanceof String str){
        System.out.println("字符串:"+str);
    }else if(obj instanceof Integer i){
        System.out.println("整数:"+i);
    }else if(obj instanceof List<?> list){
        System.out.println("集合:"+list);
    }else {
        System.out.println("unknown");
    }
}

Java 17就可以用Swicth模式匹配来简化代码:

public static void main(String[] args) {
    Object obj = new Object();
    switch (obj){
        case String str->System.out.println("字符串:"+str);
        case Integer i->System.out.println("整数:"+i);
        case List<?> list->System.out.println("集合:"+list);
        default -> System.out.println("unknown");
    }
}

2.3 JEP 409: 封闭类(转正)

  • 密封类由 JEP 360 提出,并在 JDK 15 中作为预览功能提供。

  • JEP 397 再次提出了这些建议,并对其进行了改进,并在 JDK 16 中作为预览功能提供。

  • JDK 17封闭类成为正式特性,与 JDK 16 相比没有变化。

ps:参考1.3小节

2.4 JEP 412:外部函数和内存API(第一轮孵化)

改进了 JDK 14 和 JDK 15 中引入的孵化 API,使 Java 程序能够与 Java 运行时之外的代码和数据进行互操作。通过有效地调用外部函数(即 JVM 之外的代码)和安全地访问外部内存,这些 API 使 Java 程序能够调用本地库和处理本地数据,而不会像 Java 本地接口 (JNI) 那样脆弱和复杂。

该JEP 中提出的 API 是两个孵化 API 的演变:外部内存访问 API 和外部链接器 API。

  • 外部内存访问 API 最初由 JEP 370 提出,并于 2019 年底作为孵化 API 针对 Java 14;

  • 它在 Java 15 中由 JEP 383 和 Java 16 中的 JEP 393 重新孵化。外部链接器 API 最初由 JEP 389 提出,并于 2020 年底针对 Java 16,也是一个孵化 API。

第一个预览版本在Java 19提出,所以将会在Java 19再详细介绍。

2.5 JEP 414:向量API(第二轮孵化)

ps:参考1.1小节。

  • 向量API 由 JEP 338 提出,并作为孵化 API 集成到 Java 16 中。

  • 在Java 17进行了第二轮孵化。

Java 17的相关改进:

  • 对 API 的增强,以支持字符操作,例如 UTF-8 字符解码。具体来说,添加了用于在短向量和字符数组之间复制字符的方法,以及用于与整数向量进行无符号比较的新向量比较操作符。

  • 对 API 的增强,以便在字节向量和布尔数组之间进行转换。

  • 对 x64 上的超越函数和三角函数逐元素操作的内部支持,使用 Intel 的短向量数学库(SVML)。

End:希望对大家有所帮助,如果有纰漏或者更好的想法,请您一定不要吝啬你的赐教🙋。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2185976.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙OpenHarmony

开源鸿蒙系统编译指南 Ubuntu编译环境配置第一步&#xff1a;Shell 改 Bash第二步&#xff1a;安装Git和安装pip3工具第三步&#xff1a;远程仓配置第四步&#xff1a;拉取代码第五步&#xff1a;安装编译环境第六步&#xff1a;本地编译源码 Windows开发环境配置第一步&#x…

生信初学者教程(二十四):筛选交集特征

文章目录 介绍加载R包导入数据重叠的重要特征重要特征的韦恩图输出结果总结介绍 在数据分析和机器学习项目中,特征选择是一个至关重要的步骤,它有助于识别数据集中与目标变量最相关的特征。当通过不同的机器学习方法筛选出重要特征时,对这些特征取交集以识别核心特征,是一种…

【重学 MySQL】五十、添加数据

【重学 MySQL】五十、添加数据 使用INSERT INTO语句添加数据基本语法示例插入多行数据注意事项 使用LOAD DATA INFILE语句批量添加数据其他插入数据的方式注意事项 在MySQL中&#xff0c;添加数据是数据库操作中的基本操作之一。 使用INSERT INTO语句添加数据 使用 INSERT IN…

资源《Arduino UNO R3 proteus 仿真工程》说明。

资源链接&#xff1a; Arduino UNO R3 proteus 仿真工程 1.文件明细&#xff1a; 2.文件内容说明 包含&#xff1a;AD工程、原理图、PCB。 3.内容展示 4.简述 该文件为proteus工程&#xff0c;用于Arduino uno r3仿真。 因为软件自动运行&#xff0c;所以最小系统上没有…

全网最适合入门的面向对象编程教程:55 Python字符串与序列化-字节序列类型和可变字节字符串

全网最适合入门的面向对象编程教程&#xff1a;55 Python 字符串与序列化-字节序列类型和可变字节字符串 摘要&#xff1a; 在 Python 中&#xff0c;字符编码是将字符映射为字节的过程&#xff0c;而字节序列&#xff08;bytes&#xff09;则是存储这些字节的实际数据结构&am…

论文笔记:iCaRL: Incremental Classifier and Representation Learning

1. Contribution 提出了一种新的训练策略&#xff0c;iCaRL&#xff1a;允许以增量方式学习&#xff1a;只需要同时存在一小部分类别的训练数据&#xff0c;新类别可以逐步添加。同时学习分类器和数据表示&#xff1a;iCaRL能够同时学习强大的分类器和数据表示&#xff0c;这与…

OpenGL ES MVP/变换投影矩阵(8)

OpenGL ES MVP/变换投影矩阵(8) 简述 通过前面几节的学习&#xff0c;目前我们已经可以渲染自己想要的图像&#xff0c;也可以通过纹理加载图片进行渲染。接下来我们来学习一下MVP&#xff0c;这里的MVP不是Android应用开发里的框架MVP&#xff0c;而是Model&#xff0c;View…

电场能量磁场能量相等,注意电场能量公式也没有复数形式(和坡印廷类似)

下面是电场能量密度和磁场能量密度的公式&#xff0c;注意这可不是坡印廷定理。且电场能量密度没有复数表达式&#xff0c;即不是把E和D换成复数形式就行的。注意&#xff0c;一个矢量可以转化为复数形式&#xff0c;两个矢量做运算不能转化为两个复数形式的矢量做运算&#xf…

什么是SPI机制

什么是SPI机制 SPI机制是Java平台提供的一种强大的动态扩展机制&#xff0c;能够让程序在运行时灵活地加载和使用服务提供者的实现类。我们这里带大家简单的了解一下SPI机制是如何工作的 SPI&#xff08;Service Provider Interface&#xff0c;服务提供者接口&#xff09;机制…

JavaScript while循环语句

While语句包括一个循环条件和一段代码块&#xff0c;只要条件为真&#xff0c;就不断循环执行代码块。 while(条件){语句;} var i0;while(i<100){console.log(i);i1;} 注意&#xff1a;所有的for循环都可以改写为while循环

Spring Boot 和 MyBatis-Plus凑一块儿了,这份教程你得看

一、引言 MyBatis-Plus 是 MyBatis 的增强版&#xff0c;提供了 CRUD 接口、分页插件、性能分析插件等特性&#xff0c;简化了开发过程。本文将详细介绍如何在 Spring Boot 项目中集成 MyBatis-Plus。 支持的数据看也越来越多&#xff0c;值得去搞一下&#xff0c;写了一个小例…

《PMI-PBA认证与商业分析实战精析》第5章 需求启发与分析

第5章 需求启发与分析 本章主要内容&#xff1a; 需求启发 需求分析 模型化与优化需求 记录、确认、核实和批准需求 本章涵盖的考试重点&#xff1a; 需求启发的四项活动 需求启发的八项技术 启发提问的四种类型问题 启发原型的类型 访谈的四种分类 观察技术的四种类…

华三资源

华三华三官方网站华三公司官网新华三 - 融绘数字未来&#xff0c;共享美好生活华三华三文档中心华三文档资源文档中心-新华三集团-H3C华三华三 ICT百科华三 ICT知识百科H3C ICT知识百科-新华三集团-H3C华三华三文档高级查找高级文档搜索新华三 - 融绘数字未来&#xff0c;共享美…

已解决:Could not find artifact xxx

已解决&#xff1a;Could not find artifact xxx 文章目录 写在前面问题描述报错原因分析 解决思路解决办法1. 检查依赖声明的正确性2. 检查远程仓库配置3. 检查网络连接4. 清理本地缓存并强制更新5. 手动上传依赖到私有仓库6. 检查本地仓库是否已被损坏 总结 写在前面 在使用…

V2V迁移:vsphere至openstack

预检查 检测待迁移实例是否已安装并配置virtio相关的块设备驱动、网卡驱动&#xff0c;linux包括kernel、initramfs&#xff0c;windows包括磁盘控制器、网卡。 Linux 系统检查 Virtio 驱动 Windows 系统检查 Virtio 驱动 环境 1、下载安装ovftool 2、安装qemu-kvm&#x…

数据结构-二叉树介绍及其在Java中遍历算法实现

一、二叉树介绍 1、二叉树(Binary tree)的定义 二叉树(binary tree)是树形结构的一个重要类型,是指树中节点的度不大于2的有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右…

Angular基础学习(入门 --> 入坑)

目录 一、Angular 环境搭建 二、创建Angular新项目 三、数据绑定 四、ngFor循环、ngIf、ngSwitch、[ngClass]、[ngStyle]、管道、事件、双向数据绑定--MVVM 五、DOM 操作 &#xff08;ViewChild&#xff09; 六、组件通讯 七、生命周期 八、Rxjs 异步数据流 九、Http …

SuperMap iClient for MapLibreGL 根据SQL条件过滤显示动态图层

查阅发现iClient 有子图层控制类 LayerStatus 可实现&#xff1a;子图层显示参数类。此类存储了各个子图层的名称、是否可见的状态、SQL 过滤条件等参数。 API详情&#xff1a;http://support.supermap.com.cn:8090/iserver/iClient/forJavaScript/docs/maplibregl/LayerStatus…

java_整型

1.整数类型 2.整型细节 Java各整数类型有固定的范围和字段长度&#xff0c;不受具体OS【操作系统】的影响&#xff0c;以保证Java程序的可移植性 Java的整型常量&#xff08;具体值&#xff09;默认为int型&#xff0c;声明long型常量后需加"l"或"L" pu…

计算机网络:计算机网络体系结构 —— OSI 模型 与 TCP/IP 模型

文章目录 计算机网络体系结构OSI 参考模型TCP/IP 参考模型分层的必要性物理层的主要问题数据链路层的主要问题网络层的主要问题运输层的主要问题应用层的主要问题 分层思想的处理方法发送请求路由器转发接受请求发送响应接收响应 计算机网络体系结构 计算机网络体系结构是指将…