写点什么

从 Java 11 迁移到 Java 17 的注意事项

作者:高端章鱼哥
  • 2023-08-09
    福建
  • 本文字数:3416 字

    阅读完需:约 11 分钟

从 Java 11 迁移到 Java 17 的注意事项

Java17 给 Java 带来了一些变化,但也使许多开发人员重新考虑他们迁移到其他 JVM 语言的愿望。最明显的变化是在使 Java 代码现代化和添加新的语言结构以简化它的方向上进行的。当然,这个问题并非没有对 Java 核心的改变,这使得 Java 更加高效。

1、文本块


文本块功能终于出现在 Java 中。我确信这是 Java 程序员等待已久的变化之一。现在你可以忘记难以阅读的长复合行。文本块允许你以最方便的方式编写多行文本。在这样的块中,你可以按照自己希望的方式撰写文本,并且仍然可以使用转义序列进行更精确的格式设置。


Java11. 字符串转义序列:


public String poem = "                " +            "Twinkle, Twinkle, Little Star\n" +            "                \n" +            "                Twinkle, twinkle, little star,\n" +            "                How I wonder what you are!\n" +            "                Up above the world so high,\n" +            "                Like a diamond in the sky.\n" +            "                \n" +            "                Twinkle, twinkle, little star,\n" +            "                How I wonder what you are!";
复制代码


Java17.文本块:


public String poem = """                Twinkle, Twinkle, Little Star                                Twinkle, twinkle, little star,                How I wonder what you are!                Up above the world so high,                Like a diamond in the sky.                                Twinkle, twinkle, little star,                How I wonder what you are!            """;
复制代码

2、Record


另一个慢慢使 Java 语言更有用的更新是 record。以前,要创建一个类,我们需要描述该类,指定其字段,并添加必要的方法,例如 equals、hashcode、getter 和 setters。自从 record 出现以来,所有这些现在都变得不必要了。


record 允许你通过仅指定必填字段来创建数据安全类;将自动创建所有其他方法。但是,值得记住的是,record 充当数据类,创建是为了存储数据,而不是执行各种操作。record 是线程安全的,因为所有 record 字段都是最终的。最后要知道的重要一点是,用于获取字段值的生成方法不会像经典 Java Bean 中那样包含“get”。


Java11.数据类:


public class DataClass {    public DataClass (Integer id, String name) {        this.id = id;        this.name = name;    }
private final Integer id; private final String name;
public Integer getId() { return id; }
public String getName() { return name; }
@Override public boolean equals(Object o) { ... }
@Override public int hashCode() { ... }}
复制代码


Java17.Record:


public record DataClass(Integer id, String name) {}
复制代码

3、新的 switch 表达式


更改列表还包括切换表达式。这些更改不仅影响了 Switch 表达式的语法(使其编写更加简洁),还影响了功能。Switch 表达式现在返回迭代的结果,使编写代码变得更加容易,并使其更加简洁。新的开关表达式不再需要每个 case 后面都加一个 break


Java11.switch 表达式:


public String getSeasonDescription(Season season) {        String seasonDescription;        switch (season) {            case SPRING:                seasonDescription = "Flowers are blooming!";                break;            case SUMMER:                seasonDescription = "It's hot outside!";                break;            case AUTUMN:                seasonDescription = "Leaves are falling!";                break;            case WINTER:                seasonDescription = "Snow is coming!";                break;            default:                throw new IllegalStateException("Invalid season: " + season);        }        return seasonDescription;    }
复制代码


Java 17. 增强的 Switch 表达式:


public String getSeasonDescription(Season season) {        return switch (season) {            case SPRING -> "Flowers are blooming!";            case SUMMER -> "It's hot outside!";            case AUTUMN -> "Leaves are falling!";            case WINTER -> "Snow is coming!";        };    }
复制代码

4、instanceof 模式匹配


另一项设计改进也影响了操作员。现在,更安全,更简洁。通过此更改,不再需要首先检查给定对象是否是某个类的实例,然后执行强制转换;现在可以在一行中完成此操作。如前所述,这不仅仅是语法糖,而是一个更优化的运算符。


Java 11. 经典的 intanceof


public void findInstance(Object o) {        if (o instanceof String) {            String s = (String) o;            System.out.printf("Object is a string %s", s);        } else if (o instanceof Number) {            Number n = (Number) o;            System.out.printf("Object is a number %n", n);        }    }
复制代码


Java 17. 更新的 intanceof


public void findInstance(Object o) {        if (o instanceof String s) {            System.out.printf("Object is a string %s", s);        } else if (o instanceof Number n) {            System.out.printf("Object is a number %n", n);        }    }
复制代码

5、Sealed Classes 密封类


Java 17 也考虑了安全性,并朝着这个方向迈出了重要的一步。这个想法是限制类或接口的继承,同时保持其公开。结果,新的类类型,密封类,被添加到 Java 中。密封类的语法允许你指定可以使用其功能的后代。反过来,继承者还可以允许或拒绝继承,或者指定可以沿链继承的类。此功能使你可以更灵活地创建项目,并方便地调整代码的 API。


Java 17. 密封类:


public sealed class SealedClass permits AnotherSealedClass, AnotherNonSealedClass, AnotherFinalClass {}
复制代码


Java 17. 非密封继承人:


public non-sealed class AnotherNonSealedClass extends SealedClass {}
复制代码


Java17.最终继承人:


public final class AnotherFinalClass extends SealedClass {}
复制代码


Java17.密封继承人:


public sealed class AnotherSealedClass extends SealedClass permits AnotherNonSealedClassTwo {}
复制代码


Javai17.非密封继承人二级:


public non-sealed class AnotherNonSealedClassTwo extends AnotherSealedClass {}
复制代码

6、NullPointerExceptions


最后,Java 17 中一个非常有用的更新是改进的 NullPointerException!最后,在堆栈跟踪日志中,你可以看到哪个特定字段导致了 NullPointerException。仅此功能就应该鼓励你切换到 Java 17。你不再需要长时间在代码中四处寻找发生异常的险恶地方;现在 Java 将为你完成所有工作。


Java11.NPE:


public static void main(String... args) {        String s = null;        System.out.println(s.toLowerCase());    }
复制代码


Exception in thread "main" java.lang.NullPointerException at Main.main(Main.java:4)
复制代码


Java17.改进的 NPE:


public static void main(String... args){        String s = null;        System.out.println(s.toLowerCase());    }
复制代码


Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.toLowerCase()" because "s" is null at edu.javamodules/edu.javaversions.eleventoseventeen.NpeExample.main(NpeExample.java:7)
复制代码

7、其他创新


当然,这并不是 Java17 中所做的更改的全部列表,但是讨论的创新是最引人注目的。与往常一样,Java 开发人员在改进 JVM 方面做得非常出色,使其更加高效。

8、小结


Java17 中所做的所有改进都传达了一个信息:是时候切换到这个版本了。过渡承诺语法更简洁,性能得到提高。你的项目将获得安全性、灵活性和更好的错误消息。如果你已经迁移到 Java11,那么迁移到 Java17 会很顺利。Java 的竞争优势在这里大放异彩,因为向后兼容性允许你切换到 Java17 而无需更改任何代码,并利用所有更新的功能。Java17 是 Java11 以来又一个 LTS(长期支持)版本,可确保你在较长时间内收到所有必要的安全更新。


原文链接:https://hackernoon.com/is-migrating-from-java-11-to-java-17-worth-it

发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
从 Java 11 迁移到 Java 17 的注意事项_Java_高端章鱼哥_InfoQ写作社区