当前位置:首页 > 科技  > 软件

八个从Java 11到Java17中的功能提升

来源: 责编: 时间:2023-09-25 10:39:23 243观看
导读一、为什么要从Java 11迁移?尽管Java 11是一个长期支持版本,且被广泛应用于许多应用程序中,但这里有些重要的理由需要考虑迁移到Java 17:8对Java 11的支持将结束:Java 11的官方支持将持续到2023年9月,并提供扩展支持直至202

一、为什么要从Java 11迁移?

尽管Java 11是一个长期支持版本,且被广泛应用于许多应用程序中,但这里有些重要的理由需要考虑迁移到Java 17:8ShP28资讯网——每日最新资讯28at.com

  • 对Java 11的支持将结束:Java 11的官方支持将持续到2023年9月,并提供扩展支持直至2026年9月。这意味着在支持结束后,我们将不能再获得任何补丁(甚至是安全补丁)。
  • Spring 6:最新的Spring版本Spring 6需要Java 17才能正常运行,而且许多与Spring配套使用的库也将迁移到Java 17。如果你的应用程序依赖于Spring框架,那么应该考虑迁移到Java 17。
  • Java 17提供免费的Oracle JDK:Java 17采用了新的NFTC(Oracle免费条款和条件)许可证,可以在生产环境和商业用途中免费使用Oracle JDK。相比之下,Java 11不允许在这些情况下免费使用Oracle JDK。

ShP28资讯网——每日最新资讯28at.com

二、Java 17有什么新功能?

Java 17引入了一些改进和新功能,这些功能将得到长期支持。ShP28资讯网——每日最新资讯28at.com

1. 文本块

Java引入了文本块功能,这使代码更易读,并避免了不必要的字符串格式化操作。现在,我们可以将文本放在三引号之间,并在其中包含多个双引号字符串,而无需使用转义字符。下面是一个示例:ShP28资讯网——每日最新资讯28at.com

private static void jsonBlock() {    String text = """            {              "name": "John Doe",              "age": 45,              "address": "Doe Street, 23, Java Town"            }          """;    System.out.println(text);}

正如所看到的,这样可以很容易地编写需要大量使用转义字符的Json和类似的字符串。ShP28资讯网——每日最新资讯28at.com

此外,结尾的三个双引号表示文本块的开始或其在输出中的缩进。在上面的示例中,输出中每行的位置都比最后一个字符后面的双引号向后两个空格。ShP28资讯网——每日最新资讯28at.com

引入了两个新的转义字符,'/s'用于添加空格,'/n'用于删除换行符。在编写长SQL语句时特别有用。ShP28资讯网——每日最新资讯28at.com

private static void sqlStatement() {    String sql = """    SELECT id, firstName, lastName/s/    FROM Employee    WHERE departmentId = "IT" /    ORDER BY lastName, firstName""";    System.out.println(text);}

2. 改进的Switch语句

在Java 17中,对Switch语句进行了进一步的改进,可以解决忘记写break关键字导致的bug问题。ShP28资讯网——每日最新资讯28at.com

Switch表达式是一种更灵活的Switch语法形式,在每个case块中可以返回一个值,并且可以在赋值等操作中使用这些返回值。它使用箭头符号(->)代替冒号(:)来表示返回的表达式。ShP28资讯网——每日最新资讯28at.com

在此表达式中,当使用switch返回时,不需要使用break关键字来终止每个case块,但是需要使用default case。ShP28资讯网——每日最新资讯28at.com

这种改进使得Switch语句更加简洁和易读,并且减少了由于忘记写break而导致的错误。ShP28资讯网——每日最新资讯28at.com

private static void improvedSwitch(Fruit fruit) {    String text = switch (fruit) {        case APPLE, PEAR -> {            System.out.println("the given fruit was: " + fruit);            yield "Common fruit";        }        case ORANGE, AVOCADO -> "Exotic fruit";        default -> "Undefined fruit";    };    System.out.println(text);}

如果在switch case中进行多个操作,我们可以使用case块,并使用yield关键字表示返回值。yield在这里是上下文相关的关键字,即在函数的其他地方可以有一个变量名yield。ShP28资讯网——每日最新资讯28at.com

3. 'record'类型

Record类是一种特殊的不可变类,旨在替代数据传输对象(DTO)。ShP28资讯网——每日最新资讯28at.com

通常情况下,如果我们想在类或方法中使用一些POJO(普通Java对象),我们需要声明该类,并定义所有的getters、setters、equals和hashCode函数。例如,在其他地方使用一个样例 Fruit 类,我们需要用以下方式定义类:ShP28资讯网——每日最新资讯28at.com

public class Fruit {    private String name;    private int price;    //获取器和设置器方法、equals 和 hashcode 方法}

尽管可以使用像 lombok 这样的库来减少大部分样板代码,但是如果借助 records,可以进一步减少代码量,无需依赖额外的库。ShP28资讯网——每日最新资讯28at.com

使用 records 后,相同的代码变为:ShP28资讯网——每日最新资讯28at.com

public static void doSomething() {  record Fruit(String name, int price) {}  Fruit fruit = new Fruit("Apple", 100);  System.out.println(fruit.getPrice());}

如我们所见,使用Record类甚至可以在方法内定义一个局部的record对象。这个record对象会自动为其所有字段生成getter、setter、equals和hashCode方法。ShP28资讯网——每日最新资讯28at.com

Record中的字段是不可变的,只能通过在声明record时提供的参数进行定义。但我们可以定义静态变量。我们还可以定义一个自定义构造函数来验证字段。建议不要重写record的getter和setter,否则会影响其不可变性。ShP28资讯网——每日最新资讯28at.com

下面是一个具有多个构造函数、静态变量和方法的 record 的示例:ShP28资讯网——每日最新资讯28at.com

public record Employee(int id, String firstName,                       String lastName){   static int empToken;    // 紧凑构造函数    public Employee    {        if (id < 100) {            throw new IllegalArgumentException(                "Employee Id cannot be below 100.");        }        if (firstName.length() < 2) {            throw new IllegalArgumentException(                "First name must be 2 characters or more.");        }    }        // 另一种构造函数    public Employee(int id, String firstName)    {        this(id, firstName, null);    }    // 实例方法    public void getFullName()    {        if (lastName == null)            System.out.println(firstName());        else            System.out.println(firstName() + " "                               + lastName());    }    // 静态方法    public static int generateEmployeeToken()    {        return ++empToken;    }}

record 类的更多特性还包括:ShP28资讯网——每日最新资讯28at.com

  • 可以在 record 中使用嵌套类和接口。
  • 可以嵌套记录,嵌套记录将自动成为静态的。
  • 记录可以实现接口。
  • 可以创建泛型记录类。
  • 记录可序列化。

4. 'sealed' 类

sealed 类为我们提供了更多对扩展类的控制权。ShP28资讯网——每日最新资讯28at.com

在 Java 11 中,类可以是 final 或可扩展的。如果您想控制哪些类可以扩展您的超类,可以将所有类放在同一个包中,并将超类设为包可见性。然而,从包外部无法访问超类。例如,看下面的代码:ShP28资讯网——每日最新资讯28at.com

public abstract class Fruit {}public final class Apple extends Fruit {}public final class Pear extends Fruit {}
private static void problemSpace() {    Apple apple = new Apple();    Pear pear = new Pear();    Fruit fruit = apple;    class Avocado extends Fruit {};}

在这里,我们无法阻止 Avocado 扩展 Fruit 类。如果我们将 Fruit 类设置为默认访问级别,那么将无法把 apple 分配给 fruit 对象。ShP28资讯网——每日最新资讯28at.com

Java 17 引入sealed 类新特性,用于限制类的继承层级。通过使用 sealed 关键字,可以控制哪些类可以扩展或实现一个特定的父类或接口,只允许特定的类扩展我们的超类。以下是一个示例:ShP28资讯网——每日最新资讯28at.com

public abstract sealed class FruitSealed permits AppleSealed, PearSealed {}public non-sealed class AppleSealed extends FruitSealed {}public final class PearSealed extends FruitSealed {}

如我们所见,这里使用了一个新的关键字 sealed 来表示这是一个 sealed 类。使用 permits 关键字定义可以扩展的类。任何扩展 sealed 类的类都可以是 final 类,如 PearSealed,或者可以在声明类时使用 non-sealed 关键扩展的其他类,比如 AppleSealed。ShP28资讯网——每日最新资讯28at.com

这种实现允许将 AppleSealed 分配给 FruitSealed 类,但不允许 permits 关键字未定义的其他类扩展 FruitSealed 类。ShP28资讯网——每日最新资讯28at.com

5. 使用 'instanceof' 的模式匹配

在 Java 11 中,我们通常使用 instanceof 运算符来检查一个对象是否属于某个类。如果我们希望在 instance of 检查返回 true 后对其进行某些操作,需要显式将对象转换为该特定类。以下是一个示例:ShP28资讯网——每日最新资讯28at.com

private static void oldStyle() {    Object o = new Grape(Color.BLUE, 2);    if (o instanceof GrapeClass) {        Grape grape = (Grape) o;        System.out.println("This grape has " + grape.getPits() + " pits.");    }}

在这里,我们需要显式将对象转换为 Grape 类型,然后找出核数。ShP28资讯网——每日最新资讯28at.com

使用 Java 17,可以将其更改为:ShP28资讯网——每日最新资讯28at.com

private static void patternMatchingInJava17() {     Object o = new Grape(Color.BLUE, 2);     if (o instanceof Grape grape) {         System.out.println("This grape has " + grape.getPits() + " pits.");     }}

可以将 instance of 检查与 &&(and)条件配对使用,但不能使用 ||(or)条件。因为如果是“or”条件,即使 instance of 检查返回 false,语句也可能达到另一个条件。ShP28资讯网——每日最新资讯28at.com

如果 instance of 检查返回 true,变量 grape 的作用域甚至可以超出 if 块。在下面的示例中,如果对象不是 Grape 类型,将抛出 RuntimeException 异常,因此编译器在达到打印语句时会确保 grape 对象存在。ShP28资讯网——每日最新资讯28at.com

private static void patternMatchingScopeException() {    Object o = new Grape(Color.BLUE, 2);    if (!(o instanceof  Grape grape)) {        throw new RuntimeException();    }    System.out.println("This grape has " + grape.getPits() + " pits.");}

6. 有用的空指针异常(NullPointerException)

在Java 11中,当遇到空指针异常时,我们只能得到异常发生的行号,但无法得知导致空指针异常的方法或变量。ShP28资讯网——每日最新资讯28at.com

在Java 17中,错误消息得到了改进,空指针异常的消息会告诉我们导致空指针异常的具体方法调用。ShP28资讯网——每日最新资讯28at.com

public static void main(String[] args) {    HashMap<String, Grape> grapes = new HashMap<>();    grapes.put("grape1", new GrapeClass(Color.BLUE, 2));    grapes.put("grape2", new GrapeClass(Color.WHITE, 4));    grapes.put("grape3", null);    var color = ((Grape) grapes.get("grape3")).getColor();}

正如所看到的,这里试图获取一个为null的"grape3"对象的颜色。当我们比较在Java 11和Java 17中获得的错误消息时,我们可以看到错误消息的差异,现在我们确切地知道在map中对null对象调用get方法导致了异常。ShP28资讯网——每日最新资讯28at.com

// Java 11Exception in thread "main" java.lang.NullPointerException        at com.rg.java17.HelpfulNullPointerExceptions.main(HelpfulNullPointerExceptions.java:13)
// Java 17Exception in thread "main" java.lang.NullPointerException: Cannot invoke "com.rg.java17.Grape.getColor()" because the return value of "java.util.HashMap.get(Object)" is null    at com.rg.java17.HelpfulNullPointerExceptions.main(HelpfulNullPointerExceptions.java:13)

三、更多改进

1. 支持紧凑型数字格式化

在NumberFormat类中添加了一个工厂方法,用于根据Unicode标准以紧凑、人类可读的形式格式化数字。有SHORT和LONG两种格式可用,示例如下:ShP28资讯网——每日最新资讯28at.com

NumberFormat shortFormat = NumberFormat.getCompactNumberInstance(Locale.ENGLISH, NumberFormat.Style.SHORT);System.out.println(shortFormat.format(1000))NumberFormat longFormat = NumberFormat.getCompactNumberInstance(Locale.ENGLISH, NumberFormat.Style.LONG);System.out.println(shortFormat.format(1000))// 输出1K1 thousand

2. 新增日周期支持

在DateTime模式中添加了一个新的模式"B",用于指定一天中的时间。ShP28资讯网——每日最新资讯28at.com

DateTimeFormatter timeOfDayFormatter = DateTimeFormatter.ofPattern("B");System.out.println(timeOfDayFormatter.format(LocalTime.of(8, 0)));System.out.println(timeOfDayFormatter.format(LocalTime.of(13, 0)));System.out.println(timeOfDayFormatter.format(LocalTime.of(20, 0)));System.out.println(timeOfDayFormatter.format(LocalTime.of(23, 0)));System.out.println(timeOfDayFormatter.format(LocalTime.of(0, 0)));// 输出早上下午晚上夜间午夜

3. 性能基准测试

在内存使用和时间复杂度方面,Java 17相对于Java 11也有所改进。其中进行了一项基准测试,对两个版本的代码进行性能测试,让它们执行一系列任务。ShP28资讯网——每日最新资讯28at.com

一些总体结果如下:ShP28资讯网——每日最新资讯28at.com

  • 对于G1GC(默认垃圾收集器),Java 17比Java 11快8.66%,比Java 16快2.41%。
  • 对于ParallelGC(并行垃圾收集器),Java 17比Java 11快6.54%,比Java 16快0.37%。
  • 并行垃圾收集器(Java 17可用)比G1垃圾收集器(Java 11使用的垃圾收集器)快16.39%。

从Java 11迁移到Java 17可带来多项好处,包括新功能和性能改进。然而,在迁移过程中需要注意潜在的问题。许多库也会升级到支持Java 17的新版本,因此在使用外部库时需要谨慎。通过了解可能出现的问题并采取必要的步骤解决,可以确保您顺利地迁移到Java 17。ShP28资讯网——每日最新资讯28at.com

本文链接://www.dmpip.com//www.dmpip.com/showinfo-26-11262-0.html八个从Java 11到Java17中的功能提升

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: C++11中auto关键字的深入理解与应用

下一篇: Java是怎么运行起来的?深入理解Java虚拟机

标签:
  • 热门焦点
  • Mate60手机壳曝光 致敬自己的经典设计

    Mate60手机壳曝光 致敬自己的经典设计

    8月3日消息,今天下午博主数码闲聊站带来了华为Mate60的第三方手机壳图,可以让我们在真机发布之前看看这款华为全新旗舰的大致轮廓。从曝光的图片看,Mate 60背后摄像头面积依然
  • 2023 年的 Node.js 生态系统

    2023 年的 Node.js 生态系统

    随着技术的不断演进和创新,Node.js 在 2023 年达到了一个新的高度。Node.js 拥有一个庞大的生态系统,可以帮助开发人员更快地实现复杂的应用。本文就来看看 Node.js 最新的生
  • SpringBoot中使用Cache提升接口性能详解

    SpringBoot中使用Cache提升接口性能详解

    环境:springboot2.3.12.RELEASE + JSR107 + Ehcache + JPASpring 框架从 3.1 开始,对 Spring 应用程序提供了透明式添加缓存的支持。和事务支持一样,抽象缓存允许一致地使用各
  • 让我们一起聊聊文件的操作

    让我们一起聊聊文件的操作

    文件【1】文件是什么?文件是保存数据的地方,是数据源的一种,比如大家经常使用的word文档、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存数据,它既可以保
  • 零售大模型“干中学”,攀爬数字化珠峰

    零售大模型“干中学”,攀爬数字化珠峰

    文/侯煜编辑/cc来源/华尔街科技眼对于绝大多数登山爱好者而言,攀爬珠穆朗玛峰可谓终极目标。攀登珠峰的商业路线有两条,一是尼泊尔境内的南坡路线,一是中国境内的北坡路线。相
  • 苹果公司要求三星和LG Display生产「无边框」OLED iPhone显示屏

    苹果公司要求三星和LG Display生产「无边框」OLED iPhone显示屏

    据 The Elec 报道,苹果已要求其供应商为未来的 iPhone 型号开发「无边框」OLED 显示面板。苹果显然已要求三星和 LG Display 开发新的 OLED 显示面
  • 三星显示已开始为AR设备研发硅基LED微显示屏

    三星显示已开始为AR设备研发硅基LED微显示屏

    7月18日消息,据外媒报道,随着苹果首款头显产品Vision Pro在6月份正式推出,AR/VR/MR等头显产品也就将成为各大公司下一个重要的竞争领域,对显示屏这一关
  • 支持aptX Lossless无损传输 iQOO TWS 1赛道版发布限时优惠价369元

    支持aptX Lossless无损传输 iQOO TWS 1赛道版发布限时优惠价369元

    2023年7月4日,“无损音质,声动人心”iQOO TWS 1正式发布,支持aptX Lossless无损传输,限时优惠价369元。iQOO TWS 1耳机率先支持端到端aptX Lossless无
  • Android 14发布:首批适配机型公布

    Android 14发布:首批适配机型公布

    5月11日消息,谷歌在今天凌晨举行了I/O大会,本次发布会谷歌带来了自家的AI语言模型PaLM 2、谷歌Pixel Fold折叠屏、谷歌Pixel 7a手机,同时发布了Androi
Top
Baidu
map