[Java] `JDK17` 模式变量 `Pattern variable` Variable ‘request‘ can be replaced with pattern variable

简介: [Java] `JDK17` 模式变量 `Pattern variable` Variable ‘request‘ can be replaced with pattern variable

缘起

起初是在项目中写了一段代码报了黄线

if (msg instanceof FullHttpRequest) {
            FullHttpRequest request = (FullHttpRequest) msg;
            HttpHeaders headers = request.headers();
            if (headers.isEmpty()) {
                ctx.channel().close();
                return;
            }
            ...
    }

这看到黄线,不能忍啊,点一下哎

不点不知道,点了一下,咦代码确实变好看了一点,就知道刚学学新技术了~

探寻

oracle

Pattern matching involves testing whether an object has a particular structure, then extracting data from that object if there’s a match. You can already do this with Java; however, pattern matching introduces new language enhancements that enable you to conditionally extract data from objects with code that’s more concise and robust.

模式匹配包括测试对象是否具有特定的结构,如果存在匹配,则从该对象中提取数据。你已经可以用Java做到这一点。但是,模式匹配引入了新的语言增强功能,使您能够有条件地使用更简洁和健壮的代码从对象中提取数据。

Pattern Matching for the instanceof Operator

Enhance the Java programming language with pattern matching for the instanceof operator. Pattern matching allows common logic in a program, namely the conditional extraction of components from objects, to be expressed more concisely and safely.

使用instanceof操作符的模式匹配增强Java编程语言。模式匹配允许程序中的公共逻辑,即从对象中有条件地提取组件,以更简洁和安全的方式表达。

为什么引入

在项目开发过程中,我们经常会写以下类似代码,臃肿而难看。这段代码主要是进行类型判断,然后进行类型转换。

if (obj instanceof String) {
    String s = (String) obj;    // grr...
    ...
}
  • 引入模版变量之后

A pattern is a combination of (1) a predicate, or test, that can be applied to a target, and (2) a set of local variables, known as pattern variables, that are extracted from the target only if the predicate successfully applies to it.

A type pattern consists of a predicate that specifies a type, along with a single pattern variable.

The instanceof operator (JLS 15.20.2) is extended to take a type pattern instead of just a type.

模式是(1)可以应用于目标的谓词或测试,以及(2)一组称为模式变量的局部变量的组合,只有当谓词成功地应用于目标时,这些局部变量才会从目标中提取出来。

类型模式由指定类型的谓词和单个模式变量组成。

instanceof操作符(JLS 15.20.2)被扩展为接受类型模式而不仅仅是类型。

if (obj instanceof String s) {
    // Let pattern matching do the work!
    ...
}

(In this code, the phrase String s is the type pattern.) The meaning is intuitive. The instanceof operator matches the target obj to the type pattern as follows: If obj is an instance of String, then it is cast to String and the value is assigned to the variable s.

Rather than using a coarse approximation for the scope of pattern variables, pattern variables instead use the concept of flow scoping. A pattern variable is only in scope where the compiler can deduce that the pattern has definitely matched and the variable will have been assigned a value. This analysis is flow sensitive and works in a similar way to existing flow analyses such as definite assignment.

如果断言失败 obj 不是 String 则不会为 s 赋值。

纸上得来终觉浅

if (a instanceof Point p) {
    // p is in scope
    ...
}
// p not in scope here
if (b instanceof Point p) {     // Sure!
        ...
}
if (obj instanceof String s && s.length() > 5) {
    flag = s.contains("jdk");
}
if (obj instanceof String s || s.length() > 5) {    
  // Error!
    ...
}

使用模版变量重构 effective java部分例子

public final boolean equals(Object o) {
    return (o instanceof CaseInsensitiveString) 
      && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s);
}
  • 重构后
public final boolean equals(Object o) {
    return (o instanceof CaseInsensitiveString cis) 
      && cis.s.equalsIgnoreCase(s);
}

Pattern Matching for switch Expressions and Statements

概括

switch 通过表达式和语句的模式匹配以及模式语言的扩展来增强 Java 编程语言。扩展模式匹配switch允许针对多个模式测试表达式,每个模式都有一个特定的操作,以便可以简洁、安全地表达复杂的面向数据的查询。这是JDK 17 中的预览语言功能

目标

  • switch通过允许模式出现在标签中来扩展表达式和语句的表现力和适用性case
  • switch在需要时允许放松历史上的零敌意。
  • 引入两种新的模式:受保护的模式,允许使用任意布尔表达式来细化模式匹配逻辑,以及 括号模式,以解决一些解析歧义。
  • 确保所有现有switch表达式和语句继续编译而不进行任何更改并以相同的语义执行。
  • 不要引入switch与传统switch 构造分离的具有模式匹配语义的新的类似表达式或语句。
  • switch当 case 标签是模式时与 case 标签是传统常量时,不要使表达式或语句的行为有所不同。

直接看引入前后的对比

static String formatter(Object o) {
    String formatted = "unknown";
    if (o instanceof Integer i) {
        formatted = String.format("int %d", i);
    } else if (o instanceof Long l) {
        formatted = String.format("long %d", l);
    } else if (o instanceof Double d) {
        formatted = String.format("double %f", d);
    } else if (o instanceof String s) {
        formatted = String.format("String %s", s);
    }
    return formatted;
}
  • 引入 switch 增强之后
static String formatterPatternSwitch(Object o) {
    return switch (o) {
        case Integer i -> String.format("int %d", i);
        case Long l    -> String.format("long %d", l);
        case Double d  -> String.format("double %f", d);
        case String s  -> String.format("String %s", s);
        default        -> o.toString();
    };
}
jdk8
int dayOfWeek = 3;
String dayName;
switch (dayOfWeek) {
    case 1:
        dayName = "Monday";
        break;
    case 2:
        dayName = "Tuesday";
        break;
    case 3:
        dayName = "Wednesday";
        break;
    case 4:
        dayName = "Thursday";
        break;
    case 5:
        dayName = "Friday";
        break;
    case 6:
        dayName = "Saturday";
        break;
    case 7:
        dayName = "Sunday";
        break;
    default:
        dayName = "Invalid day";
        break;
}
System.out.println("Day of the week: " + dayName);
jdk17
int dayOfWeek = 3;
String dayName = switch (dayOfWeek) {
    case 1 -> "Monday";
    case 2 -> "Tuesday";
    case 3 -> "Wednesday";
    case 4 -> "Thursday";
    case 5 -> "Friday";
    case 6 -> "Saturday";
    case 7 -> "Sunday";
    default -> "Invalid day";
};
System.out.println("Day of the week: " + dayName);

总结

拥抱新技术,用就对了~

相关文章
|
存储 缓存 安全
除了变量,final还能修饰哪些Java元素
在Java中,final关键字不仅可以修饰变量,还可以用于修饰类、方法和参数。修饰类时,该类不能被继承;修饰方法时,方法不能被重写;修饰参数时,参数在方法体内不能被修改。
175 3
|
9月前
|
存储 Java
# 【Java全栈学习笔记-U1-day02】变量+数据类型+运算符
本篇笔记主要围绕Java全栈学习的第二天内容展开,涵盖了变量、数据类型、运算符以及Scanner类的应用。首先介绍了变量的概念与命名规范,以及如何定义和使用变量;接着详细讲解了Java中的基本数据类型,包括整型、浮点型、字符型、布尔型等,并通过实例演示了数据类型的运用。随后,深入探讨了各类运算符(赋值、算术、关系、逻辑)及其优先级,帮助理解表达式的构成。最后,介绍了如何利用Scanner类实现用户输入功能,并通过多个综合示例(如计算圆面积、购物打折、变量交换及银行利息计算)巩固所学知识。完成相关作业将进一步加深对这些基础概念的理解与实践能力。
197 13
|
5月前
|
Java 应用服务中间件 Docker
java-web部署模式概述
本文总结了现代 Web 开发中 Spring Boot HTTP 接口服务的常见部署模式,包括 Servlet 与 Reactive 模型、内置与外置容器、物理机 / 容器 / 云环境部署及单体与微服务架构,帮助开发者根据实际场景选择合适的方案。
227 25
|
4月前
|
安全 Oracle Java
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
370 0
JAVA高级开发必备·卓伊凡详细JDK、JRE、JVM与Java生态深度解析-形象比喻系统理解-优雅草卓伊凡
|
5月前
|
安全 Java 微服务
Java 最新技术和框架实操:涵盖 JDK 21 新特性与 Spring Security 6.x 安全框架搭建
本文系统整理了Java最新技术与主流框架实操内容,涵盖Java 17+新特性(如模式匹配、文本块、记录类)、Spring Boot 3微服务开发、响应式编程(WebFlux)、容器化部署(Docker+K8s)、测试与CI/CD实践,附完整代码示例和学习资源推荐,助你构建现代Java全栈开发能力。
676 1
|
5月前
|
存储 Java 大数据
Java 大视界 -- Java 大数据在智能家居能源消耗模式分析与节能策略制定中的应用(198)
简介:本文探讨Java大数据技术在智能家居能源消耗分析与节能策略中的应用。通过数据采集、存储与智能分析,构建能耗模型,挖掘用电模式,制定设备调度策略,实现节能目标。结合实际案例,展示Java大数据在智能家居节能中的关键作用。
|
5月前
|
Oracle Java 关系型数据库
新手必看:Java 开发环境搭建之 JDK 与 Maven
本文分享了 Java 学习中 JDK 安装配置与 Maven 使用的入门知识,涵盖 JDK 下载安装、环境变量设置、Maven 安装配置及本地仓库与镜像设置,帮助新手快速搭建 Java 开发环境。
685 0
|
6月前
|
安全 Java API
Java最新技术(JDK 11+) 及以上 Java 最新技术之集合框架实操应用详解
本示例基于Java最新技术(JDK 11+),涵盖集合框架的核心功能,结合Java 8+特性(如Stream API、Lambda表达式)与并发编程最佳实践。内容包括:List操作(初始化、Lambda过滤、Stream处理)、Map操作(流式过滤、ConcurrentHashMap原子操作、并行流)、Set操作(TreeSet排序、CopyOnWriteArraySet并发安全)、Queue/Deque操作(优先队列、双端队列)以及高级聚合操作(集合转换、分组统计、平均值计算)。 [代码下载](https://pan.quark.cn/s/14fcf913bae6)
142 4
|
7月前
|
供应链 JavaScript 前端开发
Java基于SaaS模式多租户ERP系统源码
ERP,全称 Enterprise Resource Planning 即企业资源计划。是一种集成化的管理软件系统,它通过信息技术手段,将企业的各个业务流程和资源管理进行整合,以提高企业的运营效率和管理水平,它是一种先进的企业管理理念和信息化管理系统。 适用于小微企业的 SaaS模式多租户ERP管理系统, 采用最新的技术栈开发, 让企业简单上云。专注于小微企业的应用需求,如企业基本的进销存、询价,报价, 采购、销售、MRP生产制造、品质管理、仓库库存管理、财务应收付款, OA办公单据、CRM等。
446 23