【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

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:0017654

评论

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

同步计数器设计与建模

timerring

FPGA

云小课|GaussDB(DWS)数据存储尽在掌控,冷热数据切换自如

华为云开发者联盟

开发 华为云 数据存储 企业号 2 月 PK 榜 华为云开发者联盟

react源码中的生命周期和事件系统

flyzz177

React

量化Python交易系统开发技术,合约量化系统开发源码部署方案

I8O28578624

Flink Table Store 典型应用场景

Apache Flink

大数据 flink 实时计算

【IntelliJ IDEA】idea常用快捷键汇总

No8g攻城狮

IDEA intellij IntelliJ IDEA

KCL 与其他 Kubernetes 配置管理工具的异同 - Helm 篇 - Helm 篇 [一个自研编程语言能做什么?(系列 3)]

Peefy

Kubernetes DevOps 编程语言 #开源

ITSM | Atlassian被Gartner评为IT服务管理平台魔力象限的领导者

龙智—DevSecOps解决方案

Atlassian ITSM Gartner

动态防御|零信任安全的自动化枢纽

权说安全

网络安全 零信任 动态防御

高性能存储SIG月度动态:ublk完成POC、dsms-storage在Anolis OS上成功适配

OpenAnolis小助手

技术 高性能存储 龙蜥社区 sig 月报

直呼牛逼!阿里最新SpringBoot进阶笔记涵盖了SpringBoot所有骚操作

程序知音

Java ssm springboot Java后端 Java进阶

chatgpt背后的人工和智能

刘旭东

ChatGPT

react源码分析:babel如何解析jsx

flyzz177

React

携程MySQL迁移OceanBase最佳实践|分享

OceanBase 数据库

数据库 oceanbase

我们从 CircleCI 安全事件获得的3个经验教训

SEAL安全

安全 软件供应链 企业号 2 月 PK 榜 端点保护 恶意软件检测

搞懂设计模式——代理模式 + 原理分析

京东科技开发者

jdk 代理 cglib 框架 企业号 2 月 PK 榜

Spring Data + DDD = 王炸!!

程序知音

前端leetcde算法面试套路之树

js2030code

JavaScript LeetCode

Flomesh Ingress 使用实践(三)多租户 Ingress

Flomesh

命名空间 多租户 ingress Ingress Controller

react源码中的协调与调度

flyzz177

React

一文详解TensorFlow模型迁移及模型训练实操步骤

华为云开发者联盟

人工智能 华为云 昇腾AI 企业号 2 月 PK 榜 华为云开发者联盟

前端leetcde算法面试套路之堆

js2030code

JavaScript LeetCode

Elasticsearch dynamic_templates 实战 通用配置

alexgaoyh

elasticsearch dynamic_templates index template

A100 买不到了,只有小显卡怎么训大模型

MegEngineBot

深度学习 开源 大模型 显卡、gpu MegEngine

从历代GC算法角度刨析ZGC

京东科技开发者

ZGC JVM GC算法 垃圾回收算法 企业号 2 月 PK 榜

用javascript分类刷leetcode21.树(图文视频讲解)

js2030code

JavaScript LeetCode

Node.js 应用全链路追踪技术——全链路信息存储

vivo互联网技术

nodejs OpenTracing zipkin

区块链DEFI质押挖矿系统开发流程丨土狗币智能合约系统开发源码方案

I8O28578624

用 AI 取代人工?或许 LLMs 可以给你答案

鼎道智联

#人工智能

简单好上手!1分钟带你体验Apipost

叶小柒

【IntelliJ IDEA】idea中的插件之一:Free Mybatis plugin跳转插件的使用(方便在Dao接口和Mappper XML文件之间进行切换)

No8g攻城狮

插件 IntelliJ IDEA

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