当前位置: 首页 > news >正文

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

Java仍然是目前比较流行的编程语言,它更短的发布节奏让开发者每六个月左右就可以试用新的语言或平台功能,IntelliJ IDEA帮助我们更流畅地发现和使用这些新功能。

IntelliJ IDEA v2022.3正式版下载(Q技术交流:786598704)

在本文中,我们将只介绍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 会提示您为其组件使用模式变量,将看到此类代码以黄色背景高亮显示,可以使用 Alt+Enter 查看建议,并接受修改代码的建议:

记录模式和 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 为 null,instanceof 检查将失败:

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,并将一些模式变量的类型定义为 var:

boolean 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 Gift<T>(T t) {}

开发者可以使用以下方法解开记录 Gift 的实例,可以使用 var 或 WristWatch 作为模式变量 watch 的类型:

void unwrap(Gift<WristWatch> obj) {
if (obj instanceof Gift<WristWatch> (var watch)) {
System.out.println(watch);
}
}

但是,以下代码将不起作用:

static void cannotUnwap(Gift<object> 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 还会在此方法的间距中显示递归调用图标:

相关文章:

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

Java仍然是目前比较流行的编程语言&#xff0c;它更短的发布节奏让开发者每六个月左右就可以试用新的语言或平台功能&#xff0c;IntelliJ IDEA帮助我们更流畅地发现和使用这些新功能。IntelliJ IDEA v2022.3正式版下载(Q技术交流&#xff1a;786598704&#xff09;在本文中&am…...

js循环判断的方法

js循环判断的方法if语句if else语句if else if else if......三元表达式switchswitch语句和if语句的区别for循环while循环do while循环for inforEachfor of性能问题if语句 条件满足就执行&#xff0c;不满足就不执行 if(条件){语句}if else语句 条件满足&#xff0c;执行语句…...

git快速入门(1)

1 git的下载与安装1&#xff09;下载git安装包下载路径&#xff1a;https://git-scm.com/我的操作系统是window&#xff0c;64位的&#xff0c;我下载的Git-2.33.0-64-bit.exe&#xff0c;从官网下载或者从网址下载链接&#xff1a;链接地址&#xff1a;https://pan.baidu.com/…...

韩国绿芯1~16通道触摸芯片型号推荐

随着技术的发展&#xff0c;触摸感应技术正日益受到更多关注和应用&#xff0c;目前实现触摸感应的方式主要有两种&#xff0c;一种是电阻式&#xff0c;另一种是电容式。电容式触摸具有感应灵敏、功耗低、寿命长等特点&#xff0c;因此逐步取代电阻式触摸&#xff0c;成为当前…...

Go语言设计与实现 -- http服务器编程

Go http服务器编程 初始 http 是典型的 C/S 架构&#xff0c;客户端向服务端发送请求&#xff08;request&#xff09;&#xff0c;服务端做出应答&#xff08;response&#xff09;。 golang 的标准库 net/http 提供了 http 编程有关的接口&#xff0c;封装了内部TCP连接和…...

MySQL-视图

视图是什么&#xff1f; 一张虚表&#xff0c;和真实的表一样。视图包含一系列带有名称的行和列数据。视图是从一个或多个表中导出来的&#xff0c;我们可以通过insert&#xff0c;update&#xff0c;delete来操作视图。当通过视图看到的数据被修改时&#xff0c;相应的原表的数…...

都工作3年了,怎么能不懂双亲委派呢?(带你手把手断点源码)

&#x1f497;推荐阅读文章&#x1f497; &#x1f338;JavaSE系列&#x1f338;&#x1f449;1️⃣《JavaSE系列教程》&#x1f33a;MySQL系列&#x1f33a;&#x1f449;2️⃣《MySQL系列教程》&#x1f340;JavaWeb系列&#x1f340;&#x1f449;3️⃣《JavaWeb系列教程》…...

Hive 运行环境搭建

文章目录Hive 运行环境搭建一、Hive 安装部署1、安装hive2、MySQL 安装3、Hive 元数据配置到 Mysql1) 拷贝驱动2) 配置Metastore 到 MySQL3) 再次启动Hive4) 使用元数据服务的方式访问Hive二、使用Dbaver连接HiveHive 运行环境搭建 HIve 下载地址&#xff1a;http://archive.a…...

SAP ABAP 深度解析Smartform打印特殊符号等功能

ABAP 开发人员可以在 Smartform 输出上显示 SAP 图标或 SAP 符号。例如,需要在 SAP Smart Forms 文档上显示复选框形状的输出。SAP Smartform 文档上可以轻松显示空复选框、标记复选框以及 SAP 图标等特殊符号。 在 SAP Smartform 文档中添加一个新的文本节点。 1. 单击“更…...

React17+React Hook+TS4 最佳实践仿 Jira 企业级项目笔记

前言 个人笔记,记录个人过程,如有不对,敬请指出React17React HookTS4 最佳实践仿 Jira 企业级项目项目完成到第十章,剩下后面就没有看了,说的不是特别好 github地址:https://github.com/superBiuBiuMan/React-jira husky方便我们管理git hooks的工具 REST-API风格 https://zh…...

35- tensorboard的使用 (PyTorch系列) (深度学习)

知识要点 FashionMNIST数据集: 十种产品的分类. # T-shirt/top, Trouser, Pullover, Dress, Coat,Sandal, Shirt, Sneaker, Bag, Ankle Boot.writer SummaryWriter(run/fashion_mnist_experiment_1) # 网站显示一 tensorboard的使用 在网站显示pytorch的架构:1.1 …...

ChatGPT在工业领域的用法

在工业数字化时代&#xff0c;我们需要怎么样的ChatGPT&#xff1f; 近日&#xff0c;ChatGPT热度高居不下&#xff0c;强大的人机交互能力令人咋舌&#xff0c;在国内更是掀起一股讨论热潮。一时间&#xff0c;这场由ChatGPT引起的科技飓风&#xff0c;使得全球最顶尖科技力量…...

使用Chakra-UI封装简书的登录页面组件(React)

要求&#xff1a;使用chakra ui和react 框架将简书的登录页面的表单封装成独立的可重用的组件使用到的API&#xff1a;注册API请求方式&#xff1a;POST 请求地址&#xff1a;https://conduit.productionready.io/api/users请求数据: {"user":{ "username&quo…...

Three.js初试——基础概念(二)

前言 姊妹篇&#xff1a;Three.js初试——基础概念 介绍了 Three.js 的一些核心要素概念&#xff0c;这篇文章会讲一下它的关键要素概念。 之前我们了解到展示一个3D图像&#xff0c;必须要有场景、相机、渲染器这些核心要素&#xff0c;仅仅这些还不够&#xff0c;我们还需要…...

Qt音视频开发21-mpv内核万能属性机制

一、前言 搞过vlc内核后又顺带搞了搞mpv内核&#xff0c;mpv相比vlc&#xff0c;在文件数量、sdk开发便捷性方面绝对占优势的&#xff0c;单文件&#xff08;可能是静态编译&#xff09;&#xff0c;不像vlc带了一堆插件&#xff0c;通过各种属性来set和get值&#xff0c;后面…...

C语言学生随机抽号演讲计分系统

6.学生随机抽号演讲计分系统&#xff08;★★★★) 设计一款用于课程大作业检查或比赛计分的软件&#xff0c;基本功能: (1)设置本课程的学生总数 (2)根据本次参与的学生总数&#xff0c;随机抽取一个还未汇报演讲的学生的学号。 (3)每个学生汇报演讲完毕&#xff0c;输入该学生…...

Spring Boot 3.0系列【12】核心特性篇之任务调度

有道无术,术尚可求,有术无道,止于术。 本系列Spring Boot版本3.0.3 源码地址:https://gitee.com/pearl-organization/study-spring-boot3 文章目录 前言Spring Scheduler1. 单线程任务2. 自动配置3. 多线程异步任务Quartz1. 简介2. 核心组件2.1 Job(任务)2.2 Trigger(…...

Java操作XML

Java操作XML XML语法 一个XML文件分为文档声明、元素、属性、注释、CDATA区、特殊字符、处理指令。 转义字符 对于一些单个字符&#xff0c;若想显示其原始样式&#xff0c;也可以使用转义的形式予以处理。 & > &amp; < > < > > > " &g…...

女神节灯笼祝福【HTML+CSS】

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

CUDA并行计算基础知识

1、相关缩写术语 显卡:GPU 显卡驱动:驱动软件 GPU架构: 硬件的设计方式,例如是否有L1 or L2缓存 CUDA: 一种编程语言像C++, Python等,只不过它是专门用来操控GPU的 cudnn: 一个专门为深度学习计算设计的软件库,里面提供了很多专门的计算函数 CUDAToolkit:所谓的装cuda首先…...

【Oracle APEX开发小技巧12】

有如下需求&#xff1a; 有一个问题反馈页面&#xff0c;要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据&#xff0c;方便管理员及时处理反馈。 我的方法&#xff1a;直接将逻辑写在SQL中&#xff0c;这样可以直接在页面展示 完整代码&#xff1a; SELECTSF.FE…...

使用分级同态加密防御梯度泄漏

抽象 联邦学习 &#xff08;FL&#xff09; 支持跨分布式客户端进行协作模型训练&#xff0c;而无需共享原始数据&#xff0c;这使其成为在互联和自动驾驶汽车 &#xff08;CAV&#xff09; 等领域保护隐私的机器学习的一种很有前途的方法。然而&#xff0c;最近的研究表明&…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用

1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...

第 86 场周赛:矩阵中的幻方、钥匙和房间、将数组拆分成斐波那契序列、猜猜这个单词

Q1、[中等] 矩阵中的幻方 1、题目描述 3 x 3 的幻方是一个填充有 从 1 到 9 的不同数字的 3 x 3 矩阵&#xff0c;其中每行&#xff0c;每列以及两条对角线上的各数之和都相等。 给定一个由整数组成的row x col 的 grid&#xff0c;其中有多少个 3 3 的 “幻方” 子矩阵&am…...

如何在网页里填写 PDF 表格?

有时候&#xff0c;你可能希望用户能在你的网站上填写 PDF 表单。然而&#xff0c;这件事并不简单&#xff0c;因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件&#xff0c;但原生并不支持编辑或填写它们。更糟的是&#xff0c;如果你想收集表单数据&#xff…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...