• 关于JDK15的简单理解


    一、为什么要了解JDK15?

      2020年9月15日,Oracle官方发布了JDK15版本,及时关注官方的更新动态,可以让我们在日常开发中更合理的选择更加优秀的工具方法,避免使用一些过时的或一些即将被删除类和方法,保障程序的健壮性、稳定性、可移植性。

    二、JDK15都为我们带来了哪些东西?

    • JEP 339: Edwards-Curve 数字签名算法(EdDSA)
    • JEP 360: 密封类(预览)
    • JEP 371: 隐藏类
    • JEP 372: 删除Nashorn JavaScript引擎
    • JEP 373: 重新实现旧版DatagramSocket API
    • JEP 374: 禁用和弃用偏置锁定
    • JEP 375: instanceof的模式匹配(第二预览)
    • JEP 377: ZGC:可扩展的低延迟垃圾收集器
    • JEP 378: 文字块
    • JEP 379: Shenandoah:低暂停时间的垃圾收集器
    • JEP 381: 删除Solaris和SPARC端口
    • JEP 383: 外部存储器访问API(第二个孵化器)
    • JEP 384: Records(第二预览)
    • JEP 385: 弃用RMI激活以进行删除

    JEP:JDK Enhancement Proposals ,JDK 特性的新增和修改建议。

    三、具体说一说JDK15的特性。

    1. JEP 339: Edwards-Curve 数字签名算法(EdDSA)

    官方描述:

      EdDSA是一种现代的椭圆曲线签名方案,与JDK中的现有签名方案相比,具有多个优点。

    • 在相同的安全强度下,开发比现有的ECDSA实现(使用本机C代码)更好的性能的EdDSA平台无关的实现。例如,在安全性〜126位时使用Curve25519的EdDSA应该与在安全性〜128位时使用曲线secp256r1的ECDSA一样快。
    • 假设平台在恒定时间内执行64位整数加/乘,请确保时序与秘密无关。另外,该实现将不会基于秘密分支。这些属性对于防止侧通道攻击非常有用。

    简而言之:

      Edwards-Curve 数字签名算法(EdDSA)实现加密签名功能。且比现有的JDK 中的签名安全性和性能更高。

    2. JEP 360: 密封类(预览)

    官方描述:

      通过密封的类和接口增强Java编程语言。密封的类和接口限制可以扩展或实现它们的其他类或接口。通过将sealed修饰符应用于其声明来密封类。然后,在anyextends和implements子句之后,该permits子句指定允许扩展密封类的类。

    简而言之:

       限定接口的实现或子类,不是所有的类都能继承此类或实现此类。

    注意:

    • sealed:隐含子类 permits : 许可证
    • non-sealed:隐含非受限子类
    • final:隐含无子类
    • 每个允许的子类都只能使用修饰符 final ,sealed和non-sealed中的一个,且三者互斥。

    代码实现:

     1 // 创建Person 密封类
     2 public abstract sealed class Person permits Student, Teacher, Doctor{
     3 
     4 }
     5 
     6 // 学生类继承人类
     7 non-sealed class Student extends Person{ }
     8 
     9 // 老师类继承人类
    10 final class Teacher extends Person{ }
    11 
    12 // 医生类继承人类
    13 sealed class Doctor extends Person permits OutpDoctor, InpatDoctor{ }
    14 
    15 // 门诊医生继承人类
    16 final class OutpDoctor extends Doctor{ }
    17 
    18 // 住院医生继承人类
    19 non-sealed class InpatDoctor extends Doctor{ }
    1 // 方法类型描述
    2 public sealed interface MethodTypeDesc permits DynamicConstantDesc, MethodTypeDescImpl {}
    3 
    4 // 方法类型描述实现
    5 final class MethodTypeDescImpl implements MethodTypeDesc { }
    6 
    7 // 动态约束描述
    8 non-sealed class DynamicConstantDesc implements MethodTypeDesc {}

    3. JEP 371: 隐藏类

    官方描述:

      隐藏类是其他类的字节码不能直接使用的类。隐藏类适用于在运行时生成类并通过反射间接使用它们的框架。隐藏类可以定义为访问控制嵌套的成员,并且可以独立于其他类进行卸载。

    简而言之:

      隐藏类的超类型是由类加载器创建的,但隐藏类本身的创建并不涉及任何类加载器。所以可以方便的进行卸载且不用考虑安全问题,并且可以减少程序的内存占用。

    4. JEP 372: 删除Nashorn JavaScript引擎

    官方描述:

      随着ECMAScript语言构造以及API的快速适应和修改,我们发现Nashorn难以维护。官方决定删除Nashorn JavaScript脚本引擎和API,以及该jjs 工具。

      两个JDK模块将被永久删除:

    • jdk.scripting.nashorn-包含jdk.nashorn.api.scripting和 jdk.nashorn.api.tree软件包。
    • jdk.scripting.nashorn.shell-包含jjs工具。

    5. JEP 373: 重新实现旧版DatagramSocket API(套接字)

    官方描述: 

      用更易于维护和调试的更简单,更现代的实现来替换java.net.DatagramSocketjava.net.MulticastSocketAPI的基础实现新的实现将很容易适应虚拟线程的工作,当前正在Project Loom中进行探索

    改动原因:

      java.net.DatagramSocketjava.net.MulticastSocketAPI的代码库及其基础实现很旧且脆弱:

    • 实现可以追溯到JDK 1.0。它们是传统Java和C代码的混合,难以维护和调试。

    • 的实现MulticastSocket尤其成问题,因为它可以追溯到IPv6仍处于开发阶段。许多基本的本机实现都尝试以难以维护的方式协调IPv4和IPv6。

    • 该实现还存在一些并发问题(例如,异步关闭),需要进行大修才能正确解决。

    此外,在驻留而不是阻塞系统调用中底层内核线程的虚拟线程的情况下,当前实现不适合此目的。随着基于数据报的传输再次获得牵引力(例如 QUIC),需要更简单,更可维护的实现。

    6.JEP 374: 禁用和弃用偏置锁定

    官方描述:

      在JDK 15之前,始终启用并提供偏置锁定。使用此JEP,除非 -XX:+UseBiasedLocking 在命令行上设置,否则在启动HotSpot时将不再启用偏置锁定。

    改动原因:

      确定是否需要继续支持偏向锁定的传统同步优化,这是维护成本很高的方法。有偏见的锁定会带来争用时需要进行昂贵的撤销操作的代价。

    7.JEP 375: instanceof的模式匹配(第二预览)

    官方描述:

      通过为操作员提供模式匹配来增强Java编程语言instanceof。模式匹配使程序中的通用逻辑(即从对象中有条件地提取组件)得以更简洁,更安全地表示。

    简而言之:

      可以使我们的代码更加简洁。

    代码示例:

     1     public static void main(String[] args) {
     2         Object str = "模式匹配";
     3         // 模式匹配
     4         // 绑定变量s的作用域在&&运算符的右侧以及true块中、绑定变量s不在||右侧的范围内
     5 //        if(str instanceof String s && s.length() > 0 ){
     6         if(str instanceof String s){
     7             System.out.println(s);
     8         }else {
     9             // s不能作用于此处
    10         // System.out.printf(s);
    11         }
    12     }

    8. JEP 377: ZGC:可扩展的低延迟垃圾收集器(转正)

    官方描述:

      对ZGC的测试表明它是稳定的,并且在撰写本文时,我们已经有几个月没有收到针对ZGC的新错误了。借助ZGC如今拥有的稳定性,功能集和平台支持,是时候删除其实验状态并使其成为产品功能了。

      今天,可以通过-XX:+UnlockExperimentalVMOptions -XX:+UseZGC命令行选项启用ZGC 使ZGC成为产品(非实验性)功能意味着-XX:+UnlockExperimentalVMOptions不再需要选件。

      该JEP不建议更改默认GC,该默认GC仍为G1。

    简而言之:

      ZGC垃圾收集器在JDK15成为正式版,我们可以通过-XX:+UseZGC命令行选项启用ZGC,但是需要注意的是默认的垃圾收集器仍然是G1。

    9. JEP 378: 文字块(转正)

    官方描述:

      文本块添加到Java语言。文本块是多行字符串文字,它避免了大多数转义序列的需要,以一种可预测的方式自动设置字符串的格式,并在需要时使开发人员可以控制格式。

      解决了在Java中,在字符串文字中嵌入HTML,XML,SQL或JSON片段"..."通常需要先进行转义和串联的大量编辑,然后才能编译包含该片段的代码。该代码段通常难以阅读且难以维护的问题。

    代码示例:

     1 public static void main(String[] args) {
     2         String html = "<html>
    " +
     3                 "    <body>
    " +
     4                 "        <p>Hello, world</p>
    " +
     5                 "    </body>
    " +
     6                 "</html>
    ";
     7 
     8         String htmlText = """
     9            <html>
    10                <body>
    11                    <p>Hello, world</p>
    12                </body>
    13            </html>
    14            """;
    15 
    16         System.out.println("html长度" + html.length());
    17         System.out.println("htmlText长度" + htmlText.length());
    18 
    19         String query = "SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
    " +
    20                 "WHERE "CITY" = 'INDIANAPOLIS'
    " +
    21                 "ORDER BY "EMP_ID", "LAST_NAME";
    ";
    22 
    23         String queryText = """
    24             SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
    25             WHERE "CITY" = 'INDIANAPOLIS'
    26             ORDER BY "EMP_ID", "LAST_NAME";
    27             """;
    28 
    29         System.out.println("query长度" + query.length());
    30         System.out.println("queryText长度" + queryText.length());
    31 
    32         // :取消换行操作
    33         // s:标识一个空格
    34         String sql1 = """
    35             SELECT id, name, age 
    36             FROM persons
    37             WHERE id > 4 
    38             ORDER BY age DESC
    39             """;
    40 
    41         String sql2 = "SELECT id, name, age FROM person WHERE id > 4 ORDER BY age DESC";
    42 
    43     }

    错误代码示例:

     1 String a = """""";   // no line terminator after opening delimiter
     2 
     3 String b = """ """;  // no line terminator after opening delimiter
     4 
     5 String c = """
     6            ";        // no closing delimiter (text block continues to EOF)
     7 
     8 String d = """
     9            abc  def
    10            """;      // unescaped backslash (see below for escape processing)

    注意:

    文本块:
    """
    line 1
    line 2
    line 3
    """
    
    等效于字符串文字:
    "line 1
    line 2
    line 3
    "
    
    或字符串文字的串联:
    "line 1
    " +
    "line 2
    " +
    "line 3
    "
    
    ---------------------------------------------------------
    """
    line 1
    line 2
    line 3"""
    
    等效于字符串文字:
    "line 1
    line 2
    line 3"

    10. JEP 379: Shenandoah:低暂停时间的垃圾收集器(转正)

    官方描述:

      将Shenandoah垃圾收集器从实验功能更改为产品功能。

      在JDK 12和更高版本中,通过-XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC选项启用了Shenandoah 将Shenandoah成为产品功能意味着-XX:+UnlockExperimentalVMOptions不再需要。

    简而言之:

      Shenandoah垃圾收集器功能转正,可以通过-XX:+UseShenandoahGC直接使用,Shenandoah 的暂停时间与堆大小无关。

    11. JEP 381: 删除Solaris和SPARC端口

    官方描述:

      删除所有特定于Solaris操作系统的源代码。

      删除所有特定于SPARC体系结构的源代码。

      更新文档和源代码注释以用于将来的版本。

    改动原因:

      当前正在开发的许多项目和功能(例如Valhalla,Loom和Panama)都需要对CPU体系结构和特定于操作系统的代码进行重大更改。放弃对Solaris和SPARC端口的支持将使OpenJDK社区中的贡献者能够加速新功能的开发,这些新功能将推动平台向前发展。

    12.JEP 383: 外部存储器访问API(第二个孵化器)

    官方描述:

      引入一个API,以允许Java程序安全有效地访问Java堆之外的外部内存。

      在Java 14作为孵化API,在JDK15中第二次孵化。

      jdk.incubator.foreign相同的名称包形式提供了外部存储器访问API 它引入了三个主要抽象:MemorySegmentMemoryAddressMemoryLayout。

    13.JEP 384: Records(第二预览)

    官方描述:

      使用records增强Java编程语言,record 是充当不可变数据的透明载体的类。记录可以看作是名义元组

    • 设计一个表达简单值集合的面向对象的构造。
    • 帮助程序员专注于对不可变数据进行建模,而不是对可扩展行为进行建模。
    • 自动实现数据驱动的方法,例如equals和访问器。
    • 保留长期的Java原则,例如标称类型和迁移兼容性

    官方示例:

    例如,先前声明的记录record Point(int x, int y) { }-将被编译为:
    
    record Point(int x, int y) {
        // Implicitly declared fields
        private final int x;
        private final int y;
    
        // Other implicit declarations elided ...
    
        // Implicitly declared canonical constructor
        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }
    }

    简而言之:

      似于lombok,主要目的是为了简化作用,不用再写构造方法、equals,hashCode,toString等方法。

    代码示例:

     1 public record Student(String name,int age) {
     2 }
     3 
     4 public class Main {
     5     public static void main(String[] args) {
     6         Student student = new Student("张三",20);
     7         System.out.println(student);
     8         System.out.println(student.name());
     9         System.out.println(student.age());
    10     }
    11 }

    14.JEP 385: 弃用RMI激活以进行删除

    官方描述:

      弃用RMI激活 机制以便将来删除。RMI激活是RMI的过时部分,自Java 8开始,RMI激活是可选的。不会弃用RMI的其他部分。

    改动原因:

      分布式系统至少在过去十年中一直基于Web技术。Web服务领域已经解决了有关穿越防火墙,筛选请求,身份验证和安全性的问题。延迟实例化资源由负载平衡器,业务流程和容器处理。这些机制在分布式系统的RMI激活模型中均不存在。

      RMI激活的使用量几乎消失了。没有证据表明有任何新的应用程序被编写为使用RMI激活,并且有证据表明很少有现有应用程序使用RMI激活。对各种开放源代码库的搜索几乎没有发现任何与激活相关的API。

    间而言之:

      RMI激活的功能使用极少,Web服务有更优秀的问题解决方案,RMI激活增加了维护的费用。  

    四、总结

      总的来说,JDK15新功能不多,可以根据自己的实际需要,根据JDK版本功能走向来选择合理的功能。

  • 相关阅读:
    【Linux开发】linux设备驱动归纳总结(七):1.时间管理与内核延时
    【Linux开发】linux设备驱动归纳总结(七):1.时间管理与内核延时
    【Linux开发】linux设备驱动归纳总结(七):2.内核定时器
    【Linux开发】linux设备驱动归纳总结(七):2.内核定时器
    【Linux开发】linux设备驱动归纳总结(八):1.总线、设备和驱动
    【Linux开发】linux设备驱动归纳总结(八):1.总线、设备和驱动
    【Linux开发】linux设备驱动归纳总结(六):1.中断的实现
    【Linux开发】linux设备驱动归纳总结(六):1.中断的实现
    【Linux开发】linux设备驱动归纳总结(六):2.分享中断号
    【Linux开发】linux设备驱动归纳总结(六):2.分享中断号
  • 原文地址:https://www.cnblogs.com/wgx519/p/14303634.html
Copyright © 2020-2023  润新知