[Java]JDK17新特性

这篇具有很好参考价值的文章主要介绍了[Java]JDK17新特性。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

 文章来源地址https://www.toymoban.com/news/detail-725794.html

一、JDK新特性

1.1Java Record

1.1.1Record的使用

1.1.2Instance Methods

1.1.3静态方法 Static Method

1.1.4Record构造方法

1.1.5Record与Lombok

1.1.6Record实现接口

1.1.7Local Record

1.1.8嵌套Record

1.1.9instanceof判断Record类型

1.1.10总结

1.2Switch

1.2.1箭头表达式

1.2.2yield返回值

1.2.3Java Record

1.3Text Block

1.3.1认识文本块

1.3.2字符串比较与方法

1.3.3空白

1.3.4文本块的方法

1.3.5转义字符

1.3.6总结

1.4var

1.4.1var声明局部变量

1.4.2什么时候使用var

1.5sealed

1.5.1Sealed Classes

1.5.2Sealed Interface


 

一、JDK新特性

  • JDK8-19新增了不少新特性,这里我们把实际常用的新特性进行介绍。

    • Java Record

    • Switch 开关表达式

    • Text Block 文本块

    • var 声明局部变量

    • sealed 密封类

1.1Java Record

  • Java14中预览的新特性叫做Record,在Java中,Record是一种特殊类型的Java类。可用来创建不可变类,语法简短。

  • 任何时候创建Java类,都会创建大量的样板代码,如:

    • 每个字段的set、get方法

    • 公共的构造方法

    • 重写hashCode()、toString()、equals()方法

  • 使用Java Record避免上述的样板代码,如下特点:

    • 带有全部参数的构造方法

    • public访问器

    • toString()、hashCode()、equals()

    • 无set、get方法,没有遵循Bean的命名规范

    • final类,不能继承Record,Record为隐式的final类,除此之外与普通类一样

    • 不可变类,通过构造创建Record

    • final属性不可修改

    • 不能声明实例属性,能声明static成员

1.1.1Record的使用

  • IDEA新建Class,选择类Record

jdk17新特性,java,开发语言

1.创建 Student Record

public record Student(Integer id, String name, String email, Integer age) {
}

2.创建 Record对象

@Test
public void test01() {
    //创建Record对象
    Student student = new Student(1001, "张三", "zhangsan@qq.com", 20);
    System.out.println(student);
​
    //public访问器获取属性值,只读,没有set、get方法
    Integer id = student.id();
    String name = student.name();
    System.out.println("id=" + id);
    System.out.println("name=" + name);
​
    Student student1 = new Student(1002, "李四", "lisi@qq.com", 21);
    System.out.println(student1);
​
    System.out.println("student1.equals(student)="+student1.equals(student));
​
    System.out.println(student1.name());
    System.out.println(student1.id());
}

 

3.查看控制台输出结果

jdk17新特性,java,开发语言

 

  • Record 通过构造方法创建了只读对象,能够读取每个属性,不能设置新的属性值。

  • Record 用于创建不可变的对象,同时减少了样板代码。

  • Record 对每个属性提供了public访问器,例如student.name()

1.1.2Instance Methods

  • Record是Java类,和普通Java类一样定义方法。

1.创建实例方法

//实例方法,concat连接字符串
public String concat() {
    return String.format("姓名是%s,年龄是%d", this.name, this.age);
}

2.调用实例方法

@Test
public void test2() {
    Student student = new Student(1001, "张三", "zhangsan@qq.com", 20);
    //使用对象,调用实例方法
    System.out.println(student.concat());
}

1.1.3静态方法 Static Method

  • Record类定义静态方法,和普通类一样。

1.创建静态方法

//静态方法,把email转为大写
public static String emailToUpperCase(String email) {
    return Optional.ofNullable(email).orElse("no email").toUpperCase();
}

2.测试静态方法

@Test
public void test3() {
    //使用类,调用静态方法
    String email = Student.emailToUpperCase("zhangsan@qq.com");
    System.out.println(email);
}

1.1.4Record构造方法

  • 我们可以在Record中添加构造方法,有三种类型的构造方法:

    • 紧凑型构造方法:没有任何参数,甚至没有括号

    • 规范构造方法:以所有成员作为参数

    • 定制构造方法:自定义参数个数

1.紧凑和定制构造方法

//紧凑构造方法
public Student {
    System.out.println("id=" + id);
    if (id < 1000) {
        throw new RuntimeException("id<1000");
    }
}
​
//自定义构造方法
public Student(Integer id, String name) {
    this(id, name, null, null);
}

2.编译Student.java->Student.class

/*紧凑构造方法和规范构造方法合并了*/
public Student(Integer id, String name, String email, Integer age) {
        System.out.println("id=" + id);
        if (id < 1000) {
            throw new RuntimeException("id<1000");
        } else {
            this.id = id;
            this.name = name;
            this.email = email;
            this.age = age;
        }
    }
​
    public Student(Integer id, String name) {
        this(id, name, (String)null, (Integer)null);
    }

3.测试

@Test
public void test4() {
    Student student = new Student(1001, "张三");
    System.out.println(student);
}

1.1.5Record与Lombok

  • Java Record是创建不可变类且减少样板代码的好方法,Lombok是一种减少样板代码的工具。

  • Lombok提供语法的便利性,通常预装一些代码模板,根据您加入到类中的注解自动执行代码模板。这样的库纯粹是为了方便实现POJO类,通过预编译代码,将代码的模板加到class中。

  • Java Record是语言级别的,一种语义特性。为了建模而用,数据聚合。简单说就是提供了通用的数据类,充当“数据载体”,用于在类和应用程序之间进行数据传输。

1.1.6Record实现接口

  • Java Record可以与普通类一样实现接口,重写接口的方法。

1.创建新的接口,定义一个规范方法

public interface Print {
    void print();
}

2.创建新的Record实现接口,重写接口的方法,实现当前Record有关的业务逻辑

public record ProductRecord(Integer id, String name, Integer qty) implements Print {
    @Override
    public void print() {
        StringJoiner joiner = new StringJoiner("-");
        String s = joiner.add(id.toString()).add(name).add(qty.toString()).toString();
        System.out.println("商品信息:" + s);
    }
}

3.测试print方法

@Test
public void test5() {
    ProductRecord productRecord = new ProductRecord(1001, "电脑", 1000);
    productRecord.print();
}

1.1.7Local Record

  • Record 可以作为局部对象使用,在代码块中定义并使用Record。

定义Local Record

@Test
public void test6() {
    //定义local record
    record SaleRecord(String saleId, String productName, Double money) {}
    //创建对象
    SaleRecord saleRecord = new SaleRecord("001", "显示器", 3000.00);
​
    System.out.println("saleRecord=" + saleRecord);
}

1.1.8嵌套Record

  • 多个Record可以组合定义,一个Record能够包含其他得到Record。

1.定义Record

public record Address(String city,String address,String zipcode) {}
public record Phone(String areaCode,String number) {}
public record Customer(String id, String name, Address address, Phone phone) {}

2.创建Customer对象并测试

@Test
public void test7() {
    Address address = new Address("郑州", "新密", "452370");
    Phone phone = new Phone("0371", "60281234");
    Customer customer = new Customer("1001", "张三", address, phone);
    System.out.println(customer);
    System.out.println(customer.address().address());
    System.out.println(customer.phone().number());
}

1.1.9instanceof判断Record类型

  • instance能够与Java Record一起使用,编译器知道记录组件的确切数量和类型。

  • instanceof是Java的一个保留关键字,左边是对象,右边是类,返回类型是Boolean类型。

  • instanceof是测试左边的对象是否是右边类或者该类的子类创建的实例对象,是返回true,否返回false。

1.声明Person Record,拥有两个属性name和age

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

2.在一个业务方法判断当是Record类型时,继续判断age年龄是否满足18岁

public class SomeService {
    //定义业务方法,判断年龄是否18
    public boolean isEligible(Object obj) {
        /*if (obj instanceof Person(String name,Integer age)) {
            return age >= 18;
        }*/
        if (obj instanceof Person(String name,Integer age) p) {
            return p.age() >= 18;
        }
        return false;
    }
}

3.测试

@Test
public void test8() {
    Person person = new Person("李四", 20);
    SomeService someService = new SomeService();
    boolean flag = someService.isEligible(person);
    System.out.println(flag);
}

1.1.10总结

  • java.lang.Class类与Record类有关的两个方法

    • 判断一个类是否是Record类型:boolean isRecord()

    • Record的数组,表示此记录类的所有记录组件:RecordComponent[] getRecordComponents()

//判断Customer是否为Java Record类型
boolean record = customer.getClass().isRecord();
System.out.println("record=" + record);
​
RecordComponent[] recordComponents = customer.getClass().getRecordComponents();
for (RecordComponent recordComponent : recordComponents) {
    System.out.println("recordComponent=" + recordComponent);
}

1.2Switch

  • Switch特点:

    • 支持箭头表达式

    • 支持yield返回值

    • 支持Java Record

1.2.1箭头表达式

@Test
public void test01() {
    int week = 7;
    String memo = "";//表示计算结果
    switch (week) {
        case 1 -> memo = "星期日,休息";
        case 2, 3, 4, 5, 6 -> memo = "工作日";
        case 7 -> memo = "星期六,休息";
        default -> throw new RuntimeException("无效的日期");
    }
    System.out.println("memo=" + memo);
}

1.2.2yield返回值

  • yield让switch作为表达式,能够返回值。

  • 无需中间变量,switch作为表达式计算,可以得到结果,yield是表达式的返回值。

@Test
public void test02() {
    int week = 10;
    String memo = switch (week) {
        case 1:
            yield "周日";
        case 2, 3, 4, 5, 6:
            yield "工作日";
        case 7:
            yield "周六";
        default:
            yield "无效日期";
    };
    System.out.println("week = " + memo);
}
  • 多表达式,case与yield结合使用

@Test
    public void test03() {
        int week = 7;
        String memo = switch (week) {
            case 1 -> {
                System.out.println("周日,执行了代码块");
                yield "周日";
            }
            case 2, 3, 4, 5, 6 -> {
                System.out.println("工作日,执行了代码块");
                yield "工作日";
            }
            case 7 -> "周六";
            default -> {
                System.out.println("其它");
                throw new RuntimeException("无效日期");
            }
        };
        System.out.println("week=" + memo);
    }
  • 提示

    • case -> 不能与 case : 混用,一个switch语句块中使用一种语法格式。

1.2.3Java Record

  • switch表达式中使用record,结合case -> 表达式 ,yield实现复杂的计算。

1.准备三个Record

public record Line(int x, int y) {}
public record Circle(int r) {}
public record Rectangle(int width, int height) {}

2.switch record

@Test
public void test04() {
    Circle circle = new Circle(10);
    Line line = new Line(10, 20);
    Rectangle rectangle = new Rectangle(10, 20);
​
    Object obj = circle;
    int res = switch (obj) {
        case Circle(int r) -> {
            System.out.println("圆的半径为:" + r);
            yield 3 * r * r;
        }
        case Line(int x,int y) -> {
            System.out.println("线段的长度为:" + (y - x));
            yield y - x;
        }
        case Rectangle(int w,int h) -> w * h;
        default -> 0;
    };
    System.out.println("res=" + res);
}

1.3Text Block

  • Text Bolck处理多行文本十分方便,无需连接“+”单引号、换行符等。

1.3.1认识文本块

  • 语法:使用三个双引号括起来的字符串。

    """

    内容

    """

  • 例如:

    String name = """lisi"""; //Error 不能将文本块放在单行上
    String name= """lisi
                    20"""; //Error 文本块的内容不能在没有中间行结束符的情况下跟随三个开头双引号
    String myname= """
        zhangsan
        20
    """; //正确
    String s1 = """
        张三""";//正确

1.3.2字符串比较与方法

  • 三个双引号字符""" 与两个双引号""的字符串处理是一样的,与普通字符串一样使用。例如 equals(),"==",连接字符串("+"),作为方法的参数等。

@Test
public void fun1() {
        String s1 = """
                lisi
                """;
        String s2 = """
                lisi
                """;
        //比较字符串
        boolean b1 = s1.equals(s2);
        System.out.println("b1 = " + b1);
        //使用 == 的比较
        boolean b2 = s1 == s2;
        System.out.println("b2 = " + b2);
        String msg = """
                hello world""";
        //字符串方法 substring
        String sub = msg.substring(0, 5);
        System.out.println("sub = " + sub);
    }

1.3.3空白

示例:

@Test
public void test02() {
    //按tab键向右移动,保留左侧空格
    String msg = """
                <html>
                    <body>张三</body>
                </html>
            """;
    System.out.println(msg);
​
    String colors = """
            blue
            red
            green
            """;
    //indent(int space) 包含缩进,space为空格的数量
    colors = colors.indent(10);
    System.out.println(colors);
}

输出

jdk17新特性,java,开发语言

1.3.4文本块的方法

  • Text Block的格式方法 formatted()

@Test
public void test03() {
    String info= """
               Name:%s
            \nPhone:%s
            Age:%d
            """.formatted("张三","123",23);
    System.out.println(info.translateEscapes().strip());
}

jdk17新特性,java,开发语言

  • String strip():删除每行开头和结尾的空白

  • String translateEscapes():转义序列转换为字符串字面量

1.3.5转义字符

@Test
public void test04() {
    String str= """
            Spring Boot 是一个快速开发框架 \
            基于\"Spring\"框架,创建 Spring 应用 \
            内嵌 Web 服务器,以 jar 或 war 方式运行 \
            """;
    System.out.println(str);
}

jdk17新特性,java,开发语言

1.3.6总结

  • 多行字符串,应该使用Text Block

  • 当Text Block可以提高代码的清晰的时,推荐使用。例如代码中嵌入SQL语句。

  • 避免不必要的缩进,开头和结尾部分。

  • 空格和制表符不能混合使用。

  • 对于大多数多行字符串, 分隔符位于上一行的右端,并将结束分隔符位于文本块单独行上。

1.4var

  • 在JDK10及更高版本中,可以使用var标识符声明具有非空初始化式的局部变量,这可以帮助您编写简洁的代码,消除冗余信息使代码更具有可读性,谨慎使用。

1.4.1var声明局部变量

  • var特点

    • var 是一个保留字,不是关键字(可以声明var为变量名)

    • 方法内声明的局部变量,必须有初始值,不能为空

    • 每次声明一个变量,不能复合声明多个变量。var s1="Hello", age=20; //Error

    • var 动态类型是编译器根据变量所赋的值来推断类型

    • var代替显示类型,代码简洁,减少不必要的排版

  • var优缺点

    • 代码简洁和整齐

    • 降低了程序的可读性

示例

//通常
try (Stream<Customer> result = dbconn.executeQuery(query)) {
//...
//推荐
try (var customers = dbconn.executeQuery(query)) {
//...
}
比较 Stream<Customer> result 与 var customers

1.4.2什么时候使用var

  • 简单的临时变量

  • 复杂,多步骤逻辑,嵌套的表达式等,简短的变量有助于理解代码

  • 能够确定变量的初始值

  • 变量类型比较长时

示例

public void fun1(){
    var s1="lisi";
    var age = 20;
    for(var i=0;i<10;i++){
        System.out.println("i = " + i);
    }
    List<String> strings = Arrays.asList("a", "b", "c");
    for (var str: strings){
        System.out.println("str = " + str);
    }

1.5sealed

  • Sealed Classes 主要特点是限制继承,Java中通过继承增强,扩展了类的能力,复用某些功能。当这种能力不受控,与原有类的设计相违背,导致不预见的异常逻辑。

  • Sealed 限制无限的扩张。

  • Java种已有的sealed的设计

    • final关键字,修饰类不能被继承

    • private限制私有类

  • sealed作为关键字可以在class和interface上使用,结合permits关键字。定义限制继承的密封类。

1.5.1Sealed Classes

sealed class 类名 permits 子类1,子类2,... 列表{}

1.声明sealed Class

public sealed class Shape permits Circle,Square,Rectangle{
    public void draw(){
        System.out.println("画一个Shape");
    }
}
  • permits表示允许的子类,一个或多个

2.声明子类

  • 子类声明的三种方式

    • final 终结,依然是密封的

    • sealed 子类是密封的,需要子类实现

    • non-sealed 非密封类,扩展使用,不受限

//第一种 final
public final class Circle extends Shape {
}
//第二种 sealed class
public sealed class Square extends Shape permits RoundSquare {
    @Override
    public void draw() {
        System.out.println("=======Square 图形======");
    }
}
//密封类的子类的子类
public final class RoundSquare extends Square{
}
//非密封类 , 可以被扩展。放弃密封
public non-sealed class Rectangle extends Shape {
}
//继承非密封类
public class Line extends Rectangle{
}

1.5.2Sealed Interface

  • 密封接口同密封类

1.声明密封接口

public sealed interface SomeService permits SomeServiceImpl {
    void doSome();
}

2.实现接口

public final class SomeServiceImpl implements SomeService {
    @Override
    public void doSome() {
        System.out.println("SomeServiceImpl");
    }
}

 

 

到了这里,关于[Java]JDK17新特性的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中jdk1.8和jdk17相互切换

    之前做Java项目时一直用的是jdk1.8,现在想下载另一个jdk版本17,并且在之后的使用中可以进行相互切换,我将jdk切换时所遇到的问题记录下来并分享出来供大家参考。 环境变量配置如下: 步骤1 步骤2 (注:@MAVEN_HOME%bin;是配置maven时的环境变量,如果没有安装maven就不用管)

    2024年02月03日
    浏览(64)
  • java jdk8和jdk17同时存在【环境配置】

    jdk8:https://www.oracle.com/cn/java/technologies/javase/javase8u211-later-archive-downloads.html jdk17:https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html PS:jdk8在下载结束,安装的时候,需要有两个文件分别是jre和jdk JRE: 是Java Runtime Environment,是java程序的运行环境。既然是运行,当然要包含

    2024年02月07日
    浏览(65)
  • JDK8,JDK11,JDK17,JDK21及中间版本主要更新特性

    官方地址: https://www.oracle.com/java/technologies/java-se-support-roadmap.html 从上图可以很清晰得可以看出,JDK7,JDK8,JDK11,JDK17,JDK21是长期维护的版本。从目前来看,JDK8到2023年已经有将近10年的历史了,大多数依据JDK8的相关技术内容已经很成熟了,但是大家也看到,JDK在不断地迭代,JD

    2024年02月21日
    浏览(61)
  • JDK 8 和 JDK 17 的区别和新特性

    Java是一门广泛使用的编程语言,拥有着丰富的生态系统和大量的开发者。Java的官方实现是Oracle公司的JDK(Java Development Kit),目前最新版本是JDK 17,而JDK 8是一个长期支持版本(LTS)。 JDK 8于2014年发布,引入了许多重要的新特性,如Lambda表达式、Stream API和新的日期时间API等

    2024年02月06日
    浏览(35)
  • JDK 17 新特性 (一)

    既然 Springboot 3.0 强制使用 JDK 17 那就看看 JDK17 有哪些新特性吧 参考链接 介绍一下 新特性的历史渊源 JDK 17是Java Development Kit(JDK)的一个版本,它是Java编程语言的一种实现。JDK 17于2021年9月14日发布,并作为Java SE 17的一部分。在了解JDK 17的新特性之前,让我们先了解一下Ja

    2024年02月22日
    浏览(43)
  • Java——JDK1.8新特性

    目录 一、Lambda 表达式 (一)Lambda 表达式语法 (二)类型推断 二、函数式接口 (一)自定义函数式接口 (二)作为参数传递Lambda 表达式 (三)Java 内置四大核心函数式接口 三、方法引用 四、Stream API (一)什么是Stream? (二)Stream 的操作三个步骤 (三)创建流的四种方

    2024年02月07日
    浏览(87)
  • 【Java基础系列】JDK21新特性

    💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学习,不断总结,共同进步,活到老学到老 导航 檀越剑指大厂系列:全面总

    2024年02月04日
    浏览(43)
  • JDK21:Java21的新特性

    定于9月推出的Java21计划现在包括一个关键封装机制API和32位Windows端口的弃用。 Java开发工具包(JDK)21将于9月作为Oracle标准Java实现的下一个长期支持版本,现在有13个功能被正式提出,最近几天又增加了两个功能。 最新的提议包括密钥封装机制(KEM)API和32位x86 Windows端口的

    2024年02月07日
    浏览(44)
  • 【Java学习】-Java JDK 1.8与17版本比较

    Java Development Kit(JDK)是Java编程语言的开发环境。它包含了Java编译器(javac)、Java虚拟机(JVM)以及其他必需的工具和库。本文将比较JDK 1.8和17两个版本,分析它们的发展历史和地位,并探讨它们之间的差异和优势。 JDK 1.8,也称为Java 8,于2014年发布。它是Java平台自2006年以

    2024年02月16日
    浏览(46)
  • Java_JDK8到JDK21各版本发行时间及重要特性

    2022年Spring6和SpringBoot3相继推出,在此之前,Java社区一直是\\\"新版任你发,我用Java 8\\\",不管新版本怎么出,很少有人愿意升级。 这一次,Spring 直接来了个大招,SpringBoot3和Spring6的最低依赖就是JDK17!跨过 JDK 8-16,直接升级到 JDK 17。那么为什么是 JDK 17呢? 为什么是JDK17这么多新

    2024年01月19日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包