JDK14特性——概述&语法变化

文章目录

Java14概述

Oracle在2020年3月17日宣布JAVA14 全面上市,JAVA14通过每六个月发布一次新功能,为企业和开发人员社区提供增强功能,继续了Oracle加快创新的承诺。最新的JAVA开发工具包提供了新功能。其中包括两项备受期待的新预览功能:实例匹配的匹配模式(JEP 305) 和记录(JEP 359)以及文本块的第二个预览(JEP 368)。此外,最新的JAVA版本增加了对switch表达式的语言支持,公开了用于持续监控JDK Flight Recorder数据的新API,将低延迟的Z垃圾收集器的可用性扩招到了macOS和Windows,并在孵化器模块中添加了包装完备的java应用程序和新的外部内存访问API,以安全高效的访问JAVA对外部的内存。

可以在openjdk官网中观察到JDK14发布的详细官方计划和具体新特性详情,地址如下

https://openjdk.java.net/projects/jdk/14/

JAVA14 一共发行了16个JEP(JDK Enhancement Proposals,JDK 增强提案)

具体新增特性的介绍:

语言特性7项目:

  • switch表达式(标准)
  • 友好的空指针异常
  • 非易失性字节缓冲区
  • record
  • instanceof模式匹配
  • 文本块改进 二次预览
  • 外部存储API

垃圾回收调整:

  • G1的NUMA内存分配优化

新增工具:

  • JAVA打包工具 孵化
  • JFR事件流

增加废弃和移除:

  • MacOS系统上的ZGC试验
  • windows系统上的ZGC实验
  • 弃用Parallel Scavenge 和Serial Old垃圾收集算法
  • 弃用Solaris和SPCRC端口
  • 移除CMS垃圾收集器
  • 删除Pack200工具和API

语法变化:instanceof

以往使用instanceof运算符都是先判断,然后在进行强转,例如我们查看String的equals方法源码.

java 复制代码
 public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        // 先进行类型的判断 
        if (anObject instanceof String) {
            // 然后进行强转
            String aString = (String)anObject;
            if (!COMPACT_STRINGS || this.coder == aString.coder) {
                return StringLatin1.equals(value, aString.value);
            }
        }
        return false;
    }

需要先判断类型,然后强转,还要声明一个本地变量,语法比较麻烦,比较理想的状态是,在执行类型检测的时候同时执行类型转换。

JEP305 新增了使instanceof运算符具有匹配的能力。模式匹配能够是程序的通用逻辑更加简洁,代码更加简单,同时在做类型判断和类型转换的时候也更加安全。

JAVA14 提供了新的解决方案: 新的instanceof模式匹配,新的模式匹配语法是: 在instanceof的类型之后添加了变量。如果对obj的类型检查通过,obj会被转换成后面的变量表示的数据类型。

java 复制代码
Object obj ="hello java";
        if(obj instanceof String str){
            System.out.println(str);
        }else{
            System.out.println("not a String");
        }

上述语法的判断逻辑时,如果obj是String类型,则会转换为后面的str;如果不是,则执行else。注意,此时的str仅仅是if语句块里的局部变量,在else语句块中不可用。

语法变化:switch表达式

java的Switch语句是一个一直在变化的语法,可能是因为之前的不够强大,在JAVA14中依然可以看到对于switch的语法优化。

简单整理一下switch语句在各个版本中的特点:

版本 特性
JAVA5 switch变量类型可以使用枚举
JAVA7 switch变量类型可以使用String
JAVA11 switch语句可以自动省略break导致的贯穿提示警告
JAVA12 switch语句可以作为表达式,用变量接收结果,可以省略break
JAVA13 switch中可以使用yield关键字停止switch语句块

JAVA14 JEP361switch表达式(标准)是独立的,不依赖于JEP 325 和 JEP 354,也就是说这里开始,之前学习的switch语句的语法成为一个正式的标准。

JDK12对缺省break的贯穿弱点进行了改进,case: 改成 case L -> ,这样即使不写也不会贯穿了,而且可以作为表达式返回结果

java 复制代码
var grade ="a";
var res =switch(grade){
        case "a" -> "优秀";
        case "b" -> "良好";
        case "c" -> "一般";
        case "d" -> "及格";
        default -> "no such grade";
}

JAVA12 开始也可以进行多值匹配的支持

java 复制代码
var grade ="a";
var res =switch(grade){
        case "a","b" -> "优秀";
    	case "c" -> "一般";
        case "d" -> "及格";
        default -> "no such grade";
}

JAVA13开始可以使用 yield返回结果,这里的case后面仍然是:

java 复制代码
String x = "3";
int i = switch (x) {
case "1":
	yield 1;
case "2":{
        System.out.println("");
        yield 2;
    }

default:
yield 3;
};
System.out.println(i);

语法变化: 文本块的改进

文本块是在JAVA13中开始了第一次的预览,目标是在字符串中可以更好的表达 HTML XML SQL或者JSON格式的字符串,减少各种的不相关一些空格换行符号,字符串转义和字符串加号的拼接,在JAVA14中,增加了两个escape sequence ,分别是 \ <line-terminator>(取消换行操作) 与\s escape sequence(增加空格),文本块进行了第二次预览,进一步调了JAVA程序书写大段字符串文本的可读性和方便性。

java 复制代码
String textBlock= """
               <!DOCTYPE html>
               <html lang="en">
               <head>
                   <meta charset="UTF-8">
                   <title>Title</title>
               </head>\s\
               <body>
                              
               </body>\s
               </html>
               """;
        System.out.println(textBlock);

语法变化: Records记录类型

通过Record增强java编程语言,Record提供了一种紧凑的语法来声明类,这些类是浅层不可变数据的透明持有者。

我们经常听到这样的抱怨:"JAVA太冗长","JAVA规矩多"。最明显的就是最为简单数据载体的类,为了写一个数据类,开发人员必须编写许多低价值、重复、且容易出错的代码,构造函数

、getter/setter访问器 、equals、hashcode,、toString 这些东西,尽管IDE可以提供一些插件和手段优化,但是仍然没有改变这些代码依然存在。

Record是java的一种新的类型,同枚举一样,Record也是对类的一种限制。Record放弃了类通常享有的特性:将API和表示解耦,但是作为回报,record使数据类型变得非常简洁,一般可以帮助我们定义一些简单的用于传递数据的实体类。

一个record具有名称和状态描述,状态描述声明了record的组成部分:

java 复制代码
record Person(String name ,int age){}

因为record在与以上是数据的简单透明持有者,所以record会自动获取很多的标准成员

  • 状态声明中的每个成员,都是一个private final的字段,属性设置值则不可修改
  • 状态声明中的每个组件的公共读取访问方法,该方法和组件具有相同的名字,get方法和属性名一致
  • 一个公共的构造函数,其签名与状态声明相同,构造方法和签名合二为一
  • equals和hashcode的实现
  • toString的实现
  • record提供的默认是一个全参的构造器

测试代码如下

java 复制代码
public class Test2 {
    public static void main(String[] args) {
        Person p =new Person(1,"张三",10);
        Person p2 =new Person(1,"张三",10);
        System.out.println(p.pname());
        System.out.println(p);
        System.out.println(p.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p.equals(p2));
    }
}
record Person(Integer pid,String pname ,Integer page){};

Records限制

records类是隐含的final类,并且不是抽象类,records不能拓展任何类,不能被继承,声明的任何其他字段都必须是静态的。

Records额外的变量类型

可以显示声明从状态描述自动派生的任何成员,可以在没有正式参数列表的情况下声明构造函数,并且在正常的构造函数主体正常完成是调用隐式初始化,这样就可以在显示构造函数中仅执行其参数的验证逻辑,并且省略字段的初始化。

java 复制代码
package com.msb.test;

import java.util.Objects;

public class Test2 {
    public static void main(String[] args) {
        Person p =new Person(1,"张三",10);
        Person p2 =new Person(1,"张三",10);
        System.out.println(p.pname());
        System.out.println(p);
        System.out.println(p.hashCode());
        System.out.println(p2.hashCode());
        System.out.println(p.equals(p2));

    }
}
record Person(Integer pid,String pname ,Integer page){
    // 定义额外的变量必须是静态的,不能定义成员变量
    private static String name;
    public static void setName(String name){
        Person.name=name;
    }
    // 可以定义其他实例方法
    public void eat(){
        System.out.println("eat");
    }
    // 可以定义其他静态方法
    public static void methodA(){
        System.out.println("methoA");
    }
    // 这里是构造函数,默认就是全参的构造函数,和record声明的参数列表是一致的,
    // 这里可以使用全参构造函数中的所有参数
    // 在这里会默认执行参数给属性赋值操作,就是在这里默认会有this.pid=pid,this.pname=pname,this.page=page
    public Person{
        System.out.println(pid);
        System.out.println(pname);
        System.out.println(page);
    }
};
相关推荐
qq_4419960523 分钟前
Mybatis官方生成器使用示例
java·mybatis
Qter_Sean24 分钟前
自己动手写Qt Creator插件
开发语言·qt
何曾参静谧29 分钟前
「QT」文件类 之 QIODevice 输入输出设备类
开发语言·qt
巨大八爪鱼29 分钟前
XP系统下用mod_jk 1.2.40整合apache2.2.16和tomcat 6.0.29,让apache可以同时访问php和jsp页面
java·tomcat·apache·mod_jk
爱吃生蚝的于勒1 小时前
C语言内存函数
c语言·开发语言·数据结构·c++·学习·算法
码上一元2 小时前
SpringBoot自动装配原理解析
java·spring boot·后端
计算机-秋大田2 小时前
基于微信小程序的养老院管理系统的设计与实现,LW+源码+讲解
java·spring boot·微信小程序·小程序·vue
小白学大数据3 小时前
Python爬虫开发中的分析与方案制定
开发语言·c++·爬虫·python
魔道不误砍柴功4 小时前
简单叙述 Spring Boot 启动过程
java·数据库·spring boot
冰芒猓4 小时前
SpringMVC数据校验、数据格式化处理、国际化设置
开发语言·maven