尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Java 19和IntelliJ IDEA,如何和谐共生?

Java 19和IntelliJ IDEA,如何和谐共生? Java仍然是目前比较流行的编程语言它更短的发布节奏让开发者每六个月左右就可以试用新的语言或平台功能IntelliJ IDEA帮助我们更流畅地发现和使用这些新功能。在本文中我们将只介绍Java 19的语言功能记录模式和switch模式匹配第三版预览特意避开其他Java 19功能例如预览API虚拟线程。​​​​​​​IntelliJ IDEA支持虚拟线程的基本语法高亮显示官方团队正努力在调试器和分析器中添加对虚拟线程的支持。记录模式简化了对记录组件的访问比较记录模式和记录析构 – 当实例与记录结构匹配时将记录组件的值提取到一组变量它与 switch 和密封类的模式匹配等其他语言功能结合使用时效果十分惊人。switch 的模式匹配将模式添加到 switch 语句和 switch 表达式中的 case 标签可以与 switch 一起使用的选择器表达式的类型扩展为任意引用值。 另外case 标签不再限于常量值它还有助于将 if-else 语句链替换为 switch提高代码可读性。 在这篇博文中我们将介绍 switch 模式匹配第三版预览中引入的更改。先从为使用 Java 19 功能对​​​​​​​IntelliJ IDEA 进行配置开始。IntelliJ IDEA 配置IntelliJ IDEA 2022.3 中提供了对 Java 19 的支持未来的 IntelliJ IDEA 版本将提供更多支持。 要通过 Java 19 使用 switch 的模式匹配先转到 Project Settings | Project项目设置 | 项目将 Project SDK项目 SDK设为 19然后将项目语言级别设置为19 (Preview) – Record patterns, pattern matching for switch (third preview)开发者可以使用系统上已经下载的任意版本JDK也可以点击 Edit编辑然后选择 Add SDK 添加 SDK、Download JDK…下载 JDK…来下载其他版本可以从供应商列表中选择要下载的 JDK 版本。在 Modules模块选项卡上确保为模块选择相同的语言级别 –19 (Preview) – Record patterns, pattern matching for switch (third preview)选择此选项后可能会出现以下弹出窗口通知您 IntelliJ IDEA 可能会在后续版本中停止对 Java 预览语言功能的支持。 因为预览功能暂且不是永久性的并且它可能在未来的 Java 版本中发生变化甚至被移除。为什么需要记录模式数据是大多数应用程序的核心通常开发者使用的应用程序可以查找数据或者以帮助开发者做出决策的方式处理数据。当然如果应用程序无法存储、检索或处理其数据这是不可行的。在最近的一个 Java 版本第 16 版中记录被添加到 Java 语言中让开发者可以轻松处理数据。 记录大幅简化了对不可变数据建模的方式它们充当数据的透明载体或包装器只需使用一行代码就可以定义一条记录及其组件。例如以下单行代码会创建一条新记录 Person后者可以存储其组件 name 的字符串值和 age 的整数值record Person (String name, int age) { }记录让开发者不必些示例代码记录会隐式生成其构造函数的默认实现、其组件的访问器方法以及 toString、equals 和 hashCode 等效用函数方法。 使用记录作为数据的包装器时您很可能需要将其展开来访问其组件。 例如对于记录 Person 的实例可能想要检查其年龄组件以确定它所代表的人是否有资格投票isEligibleToVote 这样的方法可以完成这个操作boolean isEligibleToVote(Object obj) { if (obj instanceof Person person) { return person.age() 18; } return false; }前面的示例使用了 instanceof 的模式匹配它声明了一个模式变量 person因此您不需要创建局部变量来将 obj 转换为 Person。记录模式更进一步。 它不仅将实例与记录类型 Person 比较还声明了记录组件的变量因此无需定义局部变量或使用模式变量来访问记录的组件这都要归功于编译器知道记录组件的确切数量和类型。使用记录模式重写前面的方法将记录类型与 instanceof 运算符配合使用或在 switch case 标签中使用时​​​​​​​IntelliJ IDEA可以检测到它并建议使用记录模式这是修改后的代码boolean isEligibleToVote(Object obj) { if (obj instanceof Person(String name, int age)) { return age 18; } return false; }在前面的代码中记录模式 Person(String name, int age) 似乎允许使用变量 age 代替 person.age()。 然而继续阅读将了解记录模式能够简化代码的意图还有助于创建简洁的数据处理代码。命名记录模式记录模式后面可以跟随一个记录模式变量这种情况下记录模式被称为命名记录模式虽然没有得到确认但 Java 20 的记录模式的第二版预览可能会放弃对命名记录模式的支持。记录模式还可以为其组件定义模式变量用命名记录模式并尝试使用记录模式变量访问其组件时IntelliJ IDEA 会提示您为其组件使用模式变量将看到此类代码以黄色背景高亮显示可以使用 AltEnter 查看建议并接受修改代码的建议记录模式和 null我们回顾一下上一部分中的 isEligibleToVote 方法示例如果将 null 值传递给以下方法会发生什么boolean isEligibleToVote(Object obj) { if (obj instanceof Person(String name, int age)) { return age 18; } return false; }由于 null 不是记录模式 Person(String name, int age) 的实例instanceof 运算符返回 false并且模式变量 name 和 age 未初始化。这很方便因为记录模式会处理null开发者不需要定义非 null 检查。但是如果组件 name 的值为 null则模式将被匹配。嵌套记录模式 – 简洁的代码和明确的意图将另一条记录定义为其组件的记录相当常见例如record Name (String fName, String lName) { } record PhoneNumber(String areaCode, String number) { } record Country (String countryCode, String countryName) { } record Passenger (Name name, PhoneNumber phoneNumber, Country from, Country destination) { }如果没有可以检查 null 组件值的记录模式您将需要几个 null 检查运算来处理记录 Passenger 的 fName 和 countryCode 的组件值如下所示boolean checkFirstNameAndCountryCode (Object obj) { if (obj ! null) { if (obj instanceof Passenger passenger) { Name name null; Country destination null; if (passenger.name() ! null) { name passenger.name(); if (passenger.destination() ! null) { destination passenger.destination(); String fName name.fName(); String countryCode destination.countryCode(); if (fName ! null countryCode ! null) { return fName.startsWith(Simo) countryCode.equals(PRG); } } } } } return false; }同样的行为可以通过嵌套记录模式实现这也将使代码的意图更加清晰。 如果记录组件 name 和 destination 为 nullinstanceof 检查将失败boolean checkFirstNameAndCountryCodeAgain (Object obj) { if (obj instanceof Passenger(Name (String fName, String lName), PhoneNumber phoneNumber, Country from, Country (String countryCode, String countryName) )) { if (fName ! null countryCode ! null) { return fName.startsWith(Simo) countryCode.equals(PRG); } } return false; }如前面的示例代码所示开发者可以有选择地添加主记录组件的记录模式。 例如前面的示例没有为组件 from 使用记录模式但它为主记录 Passenger 的记录组件目标使用记录模式。 简而言之定义记录模式时开发者可以控制要提取到模式变量的详细信息这一功能非常适合数据处理密集型应用程序。将var与记录模式一起使用来回顾一下前面示例中的方法 checkFirstNameAndCountryCodeAgain并将一些模式变量的类型定义为 varboolean checkFirstNameAndCountryCodeAgain (Object obj) { if (obj instanceof Passenger(Name (String fName, var lName), var phoneNumber, Country from, Country (var countryCode, String countryName) )) { if (fName ! null countryCode ! null) { return fName.startsWith(Simo) countryCode.equals(PRG); } } return false; }开发者可以将部分或全部模式变量的类型定义为var如果您好奇它们的类型IntelliJ IDEA 可以显示记录模式和泛型如果记录是泛型则其记录模式必须使用泛型类型。 例如假设类 WristWatch 和泛型记录 Gift 的定义如下class WristWatch {} record GiftT(T t) {}开发者可以使用以下方法解开记录 Gift 的实例可以使用 var 或 WristWatch 作为模式变量 watch 的类型void unwrap(GiftWristWatch obj) { if (obj instanceof GiftWristWatch (var watch)) { System.out.println(watch); } }但是以下代码将不起作用static void cannotUnwap(Giftobject obj) { if (obj instanceof Gift(var s)) { // won’t compile //.. } }下一部分使用记录模式和 switch 表达式创建强大的递归方法。记录模式、switch 表达式和密封类结合记录模式、switch 表达式和密封类开发者可以创建功能强大、简洁且富有表现力的代码来处理数据。 这是密封接口 TwoDimensional 的示例它由记录 Point、Line、Triangle 和 Square 实现sealed interface TwoDimensional {} record Point (int x, int y) implements TwoDimensional { } record Line ( Point start, Point end) implements TwoDimensional { } record Triangle( Point pointA, Point pointB, Point PointC) implements TwoDimensional { } record Square ( Point pointA, Point pointB, Point PointC, Point pointD) implements TwoDimensional { }下面的方法定义了一个递归方法进程它使用 switch 构造返回二维图形如 Line、Triangle 或 Square中所有点的 x 和 y 坐标之和static int process(TwoDimensional twoDim) { return switch (twoDim) { case Point(int x, int y) - x y; case Line(Point a, Point b) - process(a) process(b); case Triangle(Point a, Point b, Point c) - process(a) process(b) process(c); case Square(Point a, Point b, Point c, Point d) - process(a) process(b) process(c) process(d); }; }IntelliJ IDEA 还会在此方法的间距中显示递归调用图标
返回列表