Java新特性梳理——Java15


highlight: xcode

theme: vuepress

概述

2020 年 9 月 15 日,Java 15 正式发布,(风平浪静的一个版本)共有 14 个 JEP,是时间驱动形式发布的第六个版本。相关文档:https://openjdk.java.net/projects/jdk/15/

image.png

语法层面变化

密封类

通过密封的类和接口来增强 Java 编程语言,这是新的预览特性,用于限制超类的使用密封的类和接口限制其他可继承或者实现他们的其他类或接口。

目标:

允许类或接口的开发者来控制那些代码负责实现,提供了比限制使用超类的访问修饰符声明方式更多选择,并通过支持对模式的详尽分析而支持模式匹配的未来发展。

在 Java 中,类层次构造通过集成实现代码的重用,父类的方法可以被许多子类继承。但是,类层次接口的目的并不总是重用代码,有时是对域中存在的各种可能性进行建模。例如图形库支持函的形状类型。当以这种方式使用类层次结构时,我们可能需要限制子类集从而简化建模。

虽然我们可以通过 final 来限定子类继承,但是这是绝对杜绝类子类。而类的密封是允许子类,限定是哪个或者哪些。

引入 Seald class 或 interface,这些 class 或者 interface 只允许被指定的类或者 interface 进行扩展和实现。

使用修饰符 sealed,我们可以将一个类声明为密封类。密封类使用 reserved 关键字 permits 列出可以直接扩展他的类。子类可以是最终的,非密封或者密封的。

示例代码:

```java public class TestSealedClass {

}

/** * sealed 对 Person 类进行密封 * permits 指明哪些类可以继承 * 子类必须是 final 修饰的或者也是密封的 * 如果子类不想被密封,可以使用 non-sealed 修饰 */ sealed class Person permits Worker, Teacher, Cook, Boss, Employee, Student {} final class Cook extends Person {} final class Boss extends Person {} final class Employee extends Person {} final class Teacher extends Person {}

// 密封的子类允许继续有子类 sealed class Student extends Person permits PrimaryStudent, GraduateStudent {} final class PrimaryStudent extends Student {} final class GraduateStudent extends Student {}

// 通过 non-sealed 取消子类密封 non-sealed class Worker extends Person {} class CarWorker extends Worker {} ```

密封接口:指定实现类的接口。

```java public class TestSealedInterface {

}

/** * 只有接口可以继承接口 * 一个接口可以同时继承多个接口 * final 不能修饰接口,密封接口在被继承时,子接口要么使用 sealed non-sealed 修饰 */ sealed interface Myinter1 permits Myinter3 {} sealed interface Myinter2 permits Myinter3 {} sealed interface Myinter3 extends Myinter1, Myinter2 {} non-sealed class MyImpl implements Myinter3 {}

sealed interface I permits A, B, C {} final class A implements I {} sealed class B implements I {} non-sealed class C implements I {}

final class D extends B {} ```

密封接口与模式匹配

```java public class TestSealedClass { public static void test(C c) { if (c instanceof I) { System.out.println( "it is an i"); } else { System.out.println("it is not i"); } }

public static void main(String[] args) {
    test(new C());
}

}

interface I {

}

// 密封类仅仅是控制类的继承和实现关系,不会影响我们的模式匹配 sealed class C implements I permits D, E {} non-sealed class D extends C {} final class E extends C {}

```

密封接口和record

record 类型是隐匿式的 final 类,可以直接实现密封接口。

```java public class TestRecords { public static void main(String[] args) { MyInter1 myInter1 = new Person(10, "曹操"); } }

sealed interface MyInter1 { public void eat(); }

/** * record 默认继承的 java.lang.Record * record可以直接实现密封接口,不需要用sealed 修饰 non-sealed 修饰 * record本身是隐式的final修饰 */ record Person(Integer pid, String pname) implements MyInter1 { @Override public void eat() {

}

}

record Student(Integer pid, String pname) implements MyInter1 { @Override public void eat() {

}

}

record Cook(Integer pid, String pname) implements MyInter1 { @Override public void eat() {

}

}

record Worker(Integer pid, String pname) implements MyInter1 { @Override public void eat() {

}

} ```

隐藏类

该提案通过启用标准 API 来定义无法发现且有有限生命周期的隐藏类,从而提高 JVM 上所有语言的效率。JDK 内部和外部的框架将能够动态生成类,而这些类可以定义隐藏类。通常来说基于 JVM 的很多语言都有动态生成类的机制,这样可以提高语言的灵活性和效率。

  • 隐藏类天生为框架设计的,在运行时生成内部的 class
  • 隐藏类只能通过反射访问,不能直接被其他类的字节码访问。
  • 隐藏类可以独立于其他类加载和卸载,这样可以减少框架的内存占用。

什么是 hidden class?

就是不能直接被其他 class 的二进制代码使用的 class。主要被一些框架用来生成运行时类,但是这些类不能被用来直接使用的,是通过反射来调用的。

比如 Java 8 中引入的 Lambda 表达式,编译时不会将 Lambda 表达式转换为专门的类,而是在运行时将相应的字节码动态生成相应的类对象。另外使用动态代理也可以为某些类生成新的动态类。

我们希望这样的动态类有哪些特征呢?

  • 不可发现性:因为我们是为某些静态的类动态生成的动态类,所以我们希望这个动态生成的类看作是静态类的一部分,所以我们不希望除了该静态类以外的其他机制发现。
  • 访问控制:我们希望在访问控制静态类的同时,也能控制到动态生成的类。
  • 生命周期:动态生成类的声明周期一般都比较短,我们不需要将其保存和静态类的生命周期一致。

因此,我们需要一些 API 来定义无法发现的且具有有限生命周期的隐藏类,这将有助于提高基于 JVM 的语言实现效率。比如:

  • java.lang.reflect.Proxy:可以定义隐藏类作为实现代理接口的代理类。
  • java.lang.invoke.StringConcatFactory:可以生成隐藏类来保存常量连接方法。
  • java.lang.invoke.LambdaMetaFactory:可以生成隐藏的 nestmate 类,以容纳访问封闭变量的 Lambda 主体。

普通类是通过调用 ClassLoader::defineClass 创建的,而隐藏类是通过调用 Lookup::defineHiddenClass 创建的,这使 JVM 提供的字节派生一个隐藏类,链接该隐藏类,并返回提供对隐藏类的反射访问的查找对象。调用程序可以通过返回的查找对象来获取隐藏类的 Class 对象。

instanceof模式匹配

Java 14 中作为预览语言功能引入 instanceof 模式匹配,在 Java 15 中出于第二次预览,而没有任何更改。

record类型

Java 14 中引入了 record 类型,只用一个 record 可以很方便的创建一个常量类,就是一个实体类,简化专门用于存储数据的类的创建语法。在 Java 15 中,record 类型处于二次预览

text block

Java 13 开始引入文本块,Java 14 进行二次预览,Java 15 中成为一个正式的标准

关于JVM

ZGC

ZGC 是 Java 11 引入的新的垃圾收集器,经历了多个阶段。自从终于成正式特性自 2008 年以来,ZGC 已经增加了许多改进:并发类卸载、取消未使用的内存、对类数据实现共享的支持到 NUMA 感知。此外,最大的堆从 4T 增加到了16T。支持平台包括 Linux、Windows 和 MacOS。ZGC 是一个重新设计的并发垃圾收集器,通过 GC 停顿时间来提高性能,但是这并不是替换默认的 G1 垃圾收集器,只不过之前需要 -XX:+UnlockExperimentalVMOptions -XX:+UseZGC。现在只需要 -XX:+UseZGC 就可以,相信不久的将来它必然会成为默认的垃圾回收器。

Shenandoah GC算法转正

这是一个 Java 12 引入的回收算法,该算法通过正在运行的 Java 线程同时进行疏散工作来减少 GC 暂停时间。Shenandoah 的暂停时间与堆大小无关,无论是 200M 还是 200G,都具有机会一致的暂停时间。

Shenandoah 和 ZGC 对比:

  • 相同点:性能几乎认为是相同的。
  • 不同点:ZGC 是 Oracle JDK 的,而 Shenandoah 只存在于 Open JDK 中,因此使用时需要注意 JDK 版本。

Shenandoah 在 Java 12 作为实验性特性引入,在 Java 15 变为正式标准,之前需要通过 -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC 参数,现在只需要添加 -XX:+UseShenandoahGC 即可。

其他变化

edDSA签名算法

Edwards-Curve Digital Singnature Algorithm:数字曲线签名算法。

这是一个新功能,新加基于 EdWardS-Curve 数字签名算法。与 JDK 中现有的签名方案相比,EdDSA 具有更高的安全性和性能,因此备受关注。它已经在 OpenSSL 和 BoringSSL 等加密库中得到支持,在区块链领域用的比较多。

EdDSA 是一种现代椭圆曲线方案,具有 JDK 中现有签名方案的优点,EdDSA 将只在 SunECMA 提供中实现。

禁用偏向锁定

Disable and Deprecate Biased Locking:禁用偏向锁定。

在默认情况下禁用偏向锁定,并弃用所有的相关命令选项。目标是确定是否需要继续支持偏置锁定的高维护成本的遗留同步优化。HotSpot 虚拟机使用该优化来减少非竞争锁的开销。尽管某些 Java 应用程序在禁用偏向锁后可能会出现性能下降,但是偏向锁的性能提高通常不像以前那么明显。

该特性默认禁用了 biased locking(-XX:+UseBisaedLocking),并且废弃了所有相关的命令行选型。

重新实现DatagramSocketAPI

Reimplement the legcy DatagramSocketAPI:重新实现 DatagramSocketAPI。

作为 JEP 353 的后续,该方案重新实现了遗留的套接字 API。java.net.datagram.Socketjava.netMulticastSocket 的当前实现可以追溯到 JDK1.0,当时 IPV6 还在开发中。因此,当前的套接字实现尝试调和 IPV4 和 IPV6 难以维护的方式。

具体实现:

  • 通过替换 java.net.datagram 的基础实现,重新实现旧版 DatagramSocket API。
  • 更改 java.net.DatagramSocketjava.net.MulticastSocket 为更加简单,现代化的底层实现,提高了 JDK 的可维护性和稳定性。

外部存储API

Foreign-Memory Access API(Second Incubator):外部存储器访问 API。

目的是引入一个 API,以允许 Java 程序安全。有效地访问 Java 对之外的外部存储器。如本机、持久和托管堆。

有许多 Java 程序访是访问外部内存的,比如 Ignite 和 MapDB。该 API 将有助于避免与垃圾收集相关的成本以及与跨进程共享内存以及通过将文件映射到内存来序列化和返序列化内存内容相关的不可预测性。该 Java API 目前没有为访问外部内存停工令人满意的解决方案。但是在新的提议中,API 不应该破坏 JVM 的安全性。

Foreign-Memory Access API 在 Java 14 中作为 incubating API 引入,在 Java 15 中处于 Second Incubator,提供了改进。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【机器学习】基于密度的聚类算法:DBSCAN详解

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 基于密度的聚类算法:DBSCAN详解引言DBSCAN的基本概念点的分类聚类过…

JVM原理(十七):JVM虚拟机即时编译器详解

编译器无论在何时、在何种状态下把Class文件转换成与本地基础设施相关的二进制机器码,他都可以视为整个编译过程的后端。 后端编译器编译性能的好坏、代码优化质量的高低却是衡量一款商用虛拟机优秀与否的关键指标之一。 1. 即时编译器 即时编译器是一个把Java的…

19.【C语言】初识指针(重难点)

内存:所有程序的运行在内存中 用Cheat Engine查看任意程序的内存(16进制): 显示大量的数据 想要定位某个数字 ,需要知道地址(类比二维坐标) 如F8的地址为00BCB90008,所以是00BCB908(偏移) ctrlG 则有 内存单元的说明&#xff1…

动态颤抖的眼睛效果404页面源码

动态颤抖的眼睛效果404页面源码, 源码由HTMLCSSJS组成,记事本打开源码文件可以进行内容文字之类的修改,双击html文件可以本地运行效果,也可以上传到服务器里面,重定向这个界面 动态颤抖的眼睛效果404页面源码

Portainer 是一个开源的容器管理平台-非常直观好用的Docker图形化项目

在这个容器化技术大行其道的时代,Docker和Kubernetes几乎成了技术圈的新宠。可是管理起容器来,有时候还是有点头大。命令行操作对于某些小伙伴来说,可能还是有点不太友好。 今天开源君分享一个叫 Portainer 的开源项目,一个用来简…

AI大模型时代的存储发展趋势

从2022年下半年,大模型和AIGC这两个词变得极其火热,而GPU的市场也是一卡难求。对于这种迷乱和火热,让我想起了当年的比特币挖矿和IPFS。似乎世界一年一个新风口,比特币、元宇宙、NFT、AIGC,金钱永不眠,IT炒…

【React】React18 Hooks 之 useReducer

目录 useReducer案例1:useReducer不带初始化函数案例2:useReducer带初始化函数注意事项1:dispatch函数不会改变正在运行的代码的状态注意事项2:获取dispatch函数触发后 JavaScript 变量的值注意事项3:触发了reducer&am…

【MotionCap】pycharm 远程在wsl2 ubuntu20.04中root的miniconda3环境

pycharm wsl2 链接到pycharmsbin 都能看到内容,/root 下内容赋予了zhangbin 所有,pycharm还是看不到/root 下内容。sudo 安装了miniconda3 引发了这些问题 由于是在 root 用户安装的miniconda3 所以安装路径在/root/miniconda3 里 这导致了环境也是root用户的,会触发告警 WA…

Xilinx原语

1. 原语介绍 原语是 Xilinx 器件底层硬件中的功能模块,它使用专用的资源来实现一系列的功能。相比于 IP 核,原语的调用方法更简单,但是一般只用于实现一些简单的功能。本章主要用到了 BUFG、 BUFIO、 IDDR、 ODDR、IDELAYE2 和 IDELAYCTRL。…

14-29 剑和诗人3 – 利用知识图谱增强 LLM 推理能力

知识图谱提供了一种结构化的方式来表示现实世界的事实及其关系。通过将知识图谱整合到大型语言模型中,我们可以增强它们的事实知识和推理能力。让我们探索如何实现这一点。 知识图谱构建 在利用知识图谱进行语言模型增强之前,我们需要从可靠的来源构建…

AIGC | 为机器学习工作站安装NVIDIA 4070 Ti Super显卡驱动

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] 0x00 前言简述 话接上篇《AIGC | Ubuntu24.04桌面版安装后必要配置》文章,作为作者进行机器学习的基础篇(筑基期),后续将主要介绍机器学习环境之如何…

springboot+vue+mybatis图书馆借阅管理系统+PPT+论文+讲解+售后

21世纪的今天,随着社会的不断发展与进步,人们对于信息科学化的认识,已由低层次向高层次发展,由原来的感性认识向理性认识提高,管理工作的重要性已逐渐被人们所认识,科学化的管理,使信息存储达到…

项目实战--Spring Boot与PageHelper的集成及线程污染解决

一、PageHelper使用背景 公司要做个简单管理系统,要我搭建Spring BootMyBatisPageHelperRedis的项目框架然后交i给实习生来开发。这个其实很简单,但是遇到搭建和使用过程中PageHelper有好多小坑,就记录一下,避免再踩。 版本选择&…

hdu物联网硬件实验2 GPIO亮灯

学院 班级 学号 姓名 日期 成绩 实验题目 GPIO亮灯 实验目的 点亮三个灯闪烁频率为一秒 硬件原理 无 关键代码及注释 const int ledPin1 GREEN_LED; // the number of the LED pin const int ledPin2 YELLOW_LED; const int ledPin3 RED…

Java - JDK17语法新增特性(如果想知道Java - JDK17语法新增常见的特性的知识点,那么只看这一篇就足够了!)

前言:Java在2021年发布了最新的长期支持版本:JDK 17。这个版本引入了许多新的语法特性,提升了开发效率和代码可读性。本文将简要介绍一些常见的新特性,帮助开发者快速掌握并应用于实际开发中。 ✨✨✨这里是秋刀鱼不做梦的BLOG ✨…

Mysql笔记-v2【7月5日更新】

零、 help、\h、? 调出帮助 mysql> \hFor information about MySQL products and services, visit:http://www.mysql.com/ For developer information, including the MySQL Reference Manual, visit:http://dev.mysql.com/ To buy MySQL Enterprise support, training, …

深入分析 Android BroadcastReceiver (八)

文章目录 深入分析 Android BroadcastReceiver (八)1. 系统与自定义实现1.1 系统广播机制1.1.1 系统广播的实现原理1.1.2 系统广播的源码分析 1.2 自定义广播机制1.2.1 自定义广播的实现步骤1.2.2 自定义广播的源码分析 2. 广播机制设计的初衷与优势2.1 设计初衷2.2 优势 3. 总…

一文读懂轻量日志收集系统Loki工作原理

Loki 是由 Grafana Labs 开发的日志聚合系统,设计目标是提供一种高效、低成本的日志收集和查询解决方案。与传统的日志系统(如 ELK Stack)不同,Loki 不会对日志内容进行索引,而是仅对日志的元数据进行索引,…

Python数据分析案例49——基于机器学习的垃圾邮件分类系统构建(朴素贝叶斯,支持向量机)

案例背景 trec06c是非常经典的邮件分类的数据,还是难能可贵的中文数据集。 这个数据集从一堆txt压缩包里面提取出来整理为excel文件还真不容不易,肯定要做一下文本分类。 虽然现在文本分类基本都是深度学习了,但是传统的机器学习也能做。本案…

Lunaproxy与711Proxy的对比与优劣分析

今天我们来深入对比两款在市场上备受关注的代理IP服务:Lunaproxy和711Proxy。接下来,我们将从多个角度对这两款服务进行详细分析,帮助大家做出明智的选择。 优势分析 711Proxy的优势 1. 性价比高:711Proxy提供多种灵活的套餐选…