写点什么

Java 迎来增强功能字符串模板,代码简化,安全性提升

  • 2023-06-10
    北京
  • 本文字数:2409 字

    阅读完需:约 8 分钟

Java迎来增强功能字符串模板,代码简化,安全性提升

面向 JDK 21 的 JEP 430(字符串模板预览)已经从 Proposed to Target 状态提升到 Targeted 状态。该 JEP 提议用字符串模板来增强 Java 编程语言。字符串模板类似于字符串字面量,但包含嵌入式表达式,这些表达式会在运行时合并到字符串模板中。

 

现在,Java 开发人员可以使用字符串模板增强该语言的字符串字面量和文本块。字符串模板将字面量文本与嵌入式表达式及处理器相结合,用于生成特定的结果。这一新特性的目的是简化 Java 程序的编写,提高文本和表达式混合代码的可读性,增强 Java 程序从用户提供的值组成字符串时的安全性。

 

该 JEP 引入了一种新的表达式,名为模板表达式,让开发人员可以安全有效地执行字符串插值及组合字符串。模板表达式是可编程的,其功能并不限于组合字符串。它们可以根据特定于领域的规则将结构化文本转换为任何类型的对象。在模板表达式中,模板处理器在运行时将模板中的字面量文本与嵌入表达式的值组合在一起生成所需的结果。请看下面的例子:

String name = "Joan";

String info = STR."My name is \{name}";assert info.equals("My name is Joan"); // true
复制代码

 

模板表达式的语法与字符串字面量类似,但有一个前缀。上述代码的第二行包含一个模板表达式。

 

相比之下,字符串插值通常允许程序员将字符串字面量和表达式组合成单个字符串,就像许多编程语言所做的那样,与传统的字符串连接相比,这样更方便也更清晰。但是,它会生成可能被其他系统误解的危险字符串,特别是在处理 SQL 语句、HTML/XML 文档、JSON 片段、shell 脚本和自然语言文本时。为了防止安全漏洞,Java 要求开发人员使用转义或验证方法对带有嵌入式表达式的字符串进行验证和消毒。

 

更安全、更有效的解决方案是引入一种基于模板的一等字符串组合机制,该机制会自动将特定于模板的规则应用于字符串,为 SQL 语句添加转义引号,让 HTML 文档没有非法实体,以及实现无模板的消息本地化。这种方法使开发人员不用再手动对每个嵌入式表达式进行转义,并验证整个字符串。这正是 Java 模板表达式所做的,与其他流行的编程语言所使用的字符串插值完全不同。

 

在模板表达式的设计中,包含嵌入式表达式的字符串字面量或文本块是不可能直接转换为插入了表达式值的字符串的。这是为了防止危险的错误字符串在程序中传播。取而代之,模板处理器(如 STRFMT RAW)会处理字符串字面量,验证结果,并插入嵌入式表达式的值。

 

下面是一些模板表达式的例子,它们使用多行来描述 HTML 文本、JSON 文本和一个区域表格:

String title = "My Web Page";String text  = "Hello, world";String html = STR."""        <html>          <head>            <title>\{title}</title>          </head>          <body>            <p>\{text}</p>          </body>        </html>        """;
复制代码

 

它生成以下输出:

| """| <html>|   <head>|     <title>My Web Page</title>|   </head>|   <body>|     <p>Hello, world</p>|   </body>| </html>| """
复制代码

 

下面是另一个例子:

String name    = "Joan Smith";String phone   = "555-123-4567";String address = "1 Maple Drive, Anytown";String json = STR."""    {        "name":    "\{name}",        "phone":   "\{phone}",        "address": "\{address}"    }    """;
复制代码

 

类似地,它生成以下输出:

| """| {|     "name":    "Joan Smith",|     "phone":   "555-123-4567",|     "address": "1 Maple Drive, Anytown"| }| """
复制代码

 

另一个例子:

record Rectangle(String name, double width, double height) {    double area() {        return width * height;    }}

Rectangle[] zone = new Rectangle[] { new Rectangle("Alfa", 17.8, 31.4), new Rectangle("Bravo", 9.6, 12.4), new Rectangle("Charlie", 7.1, 11.23), };

String form = FMT.""" Description Width Height Area %-12s\{zone[0].name} %7.2f\{zone[0].width} %7.2f\{zone[0].height} %7.2f\{zone[0].area()} %-12s\{zone[1].name} %7.2f\{zone[1].width} %7.2f\{zone[1].height} %7.2f\{zone[1].area()} %-12s\{zone[2].name} %7.2f\{zone[2].width} %7.2f\{zone[2].height} %7.2f\{zone[2].area()} \{" ".repeat(28)} Total %7.2f\{zone[0].area() + zone[1].area() + zone[2].area()} """;
复制代码

 

上述代码生成以下输出:

| """| Description     Width    Height     Area| Alfa            17.80    31.40      558.92| Bravo            9.60    12.40      119.04| Charlie          7.10    11.23       79.73|                              Total  757.69| "
复制代码

 

Java 提供了两个模板处理器来执行字符串插值:STRFMTSTR用它(字符串化)的值替换模板中的每个嵌入式表达式,而FMT会解释出现在嵌入式表达式左侧的格式说明符。格式说明符与java.util.Formatter中定义的格式说明符相同。如果需要未经处理的原始模板,则可以使用标准的RAW模板处理器。这个处理器只是简单地返回原始模板,不做任何插值或处理。

 

此外,开发人员还可以创建自己的模板处理器,用于模板表达式的处理。模板处理器是一个提供ValidatingProcessor功能接口的对象,它的类实现了ValidatingProcessor的单一抽象方法。该方法接受StringTemplate并返回一个对象。自定义模板处理器让开发人员可以在运行时执行验证并返回任何类型的对象,而不仅仅是字符串。

 

总之,Java 模板表达式使开发人员可以轻松、安全地进行字符串插值和字符串组合。


原文链接:

https://www.infoq.com/news/2023/04/java-gets-a-boost-with-string/


相关阅读:

Java 近期新闻:Java 28 岁、Payara、Micronaut 4.0-M5、Spring 更新

快速实现不打折扣的云原生 Java 应用

Record 模式提升了 Java,能实现更具表现力的编码


2023-06-10 08:0018869

评论

发布
暂无评论
发现更多内容

Centos7下Nginx编译安装与脚本安装的记录

edd

音视频技术如何为元宇宙提供全真稳的全新体验之漫话腾讯云音视频 | 社区征文

liuzhen007

音视频 1月月更 新春征文

微信朋友圈架构设计

刘洋

#架构实战营

小程序电商业务微服务拆分及基础设施选型

swallowluo

架构实战营 #架构实战营 「架构实战营」

高效管理邮件的方式

NinetyH

工具软件 办公效率 邮件管理

「架构实战营」模块一作业

hxb

「架构实战营」

WorkPlus赋能数字政府迈入发展新阶段

WorkPlus

git 使用总结

麦可

git 开发工具

ChaosCraft:和女朋友一起来 Hackathon 表演绝活丨滑滑蛋团队访谈

PingCAP

复古冰雪传奇H5游戏详细图文架设教程

echeverra

游戏开发 游戏

什么时候该减少质量投入?

QualityFocus

质量管理 软件测试 测试思维

微信业务架构 & 学生管理系统架构

凌波微步

「架构实战营」

华山论“件”:Kafka、RabbitMQ、RocketMQ技能大比拼

华为云开发者联盟

kafka RocketMQ RabbitMQ 华为云 消息中间件

一起玩转LiteOS组件:TinyFrame

华为云开发者联盟

LiteOS 串口 LiteOS组件 TinyFrame

获奖作品公布,快来看看有没有你!

InfoQ写作社区官方

新春征文 热门活动

Linux之ps命令

入门小站

Linux

架构训练营模块一作业

苍狼

CVE-2021-4034 Linux Polkit 权限提升漏洞挖掘思路解读

腾讯安全云鼎实验室

云原生 漏洞分析

LabVIEW仪表盘识别(实战篇—6)

不脱发的程序猿

机器视觉 图像处理 LabVIEW 仪表盘识别

模块一作业--

Leo

「架构实战营」

模块六

Only

架构师实战营 「架构实战营」

我的架构学习之始

浪飞

ReactNative进阶(三十六):ES8 中 async 与 await 使用方法详解

No Silver Bullet

Async React Native await 1月月更

华为云FusionInsight连续三次获得第一,加速释放数据要素价值

华为云开发者联盟

大数据 数据湖 云原生 FusionInsight 华为云

IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?

WorkPlus

研发转岗产品经理,有什么需要注意的呢?

石云升

产品经理 产品思维 1月月更

[架构实战营]-架构实训一

邹玉麒

「架构实战营」

架构实战营5期模块1作业

lovles

「架构实战营」

JavaScript 之 Proxy

编程三昧

JavaScript 前端 Proxy 1月月更

写了这么多年后端,你知道事务脚本模式吗?

蜜糖的代码注释

Java 互联网 后端

Android Studio开发flutter快捷键及文本显示技巧。

坚果

flutter 1月月更

Java迎来增强功能字符串模板,代码简化,安全性提升_编程语言_A N M Bazlur Rahman_InfoQ精选文章