3

前瞻|Java 21 新特性 String Templates(字符串模版) - 程序猿DD

 1 year ago
source link: https://www.cnblogs.com/didispace/p/17677084.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在日常写Java的时候,对于字符串的操作是非常普遍的,其中最常见的就是对字符串的组织。也因为这个操作非常普遍,所以诞生了很多方案,总下来大概有这么几种:

  • 使用+拼接
  • 使用StringBufferSpringBuilder
  • String::format and String::formatted
  • 使用java.text.MessageFormat

下面,我们一起来学习一下Java 21中的新方案!如果您对于上面这些还不熟悉的话,建议可以先看一下这篇《Java自带的4种字符串组织和格式化方法》,了解以前的机制,这样与最新的处理方案做对比,理解会更深刻。

模版表达式

在Java 21中处理字符串的新方法称为:Template Expressions,即:模版表达式。

模版表达式是Java语言中的一种新表达式。它可以执行字符串插值,帮助开发人员通过编程的方式安全高效地组织字符串。此外,模板表达式不仅仅可以用于组织字符串,它还可以根据特定模型的规则将结构化文本转换为任何类型的对象。

下面通过一个简单的案例来认识一下它:

String blog = "blog.didispace.com";
String str = STR."My blog is \{blog}";

上述代码中的第2行就是一个模版表达式,其中主要包含三个部分:

  • 模版处理器:STR
  • 包含内嵌表达式(\{blog})的模版
  • 通过.把前面两部分组合起来,形式上类似方法调用

当模版表达式运行的时候,模版处理器会将模版内容与内嵌表达式的值组合起来,生成结果,所以上面案例中的字符串str在运行时的结果为:My blog is blog.didispace.com

多行模版表达式

还记得之前我们的Java新特性专栏中,介绍过Java 15中的文本块特性吗?类似下面这样的写法:

String html = """
    <html>
    <body>
      <h1>Java 15 新特性:文本块 | 程序猿DD</h1>
      <p>didispace.com</p>
    </body>
    </html>
    """;

模版表达式也支持类似的多行字符串处理,所以开发者可以用它来方便的组织html、json、xml等字符串内容,比如下面这样:

var json = STR."""
{
    "user": "\{name}",
    "age: \{age}
}
""";

STR模版处理器

上面案例中我们所用的STR模版处理器中的内嵌表达式都采用了字符串内容,而实际上STR模版处理器还有更多的用途。

  1. 内嵌表达式中还可以之前数学运算,比如:
int x = 10, y = 20;
String s = STR."\{x} + \{y} = \{x + y}";

最终s字符串结果为:10 + 20 = 30

  1. 内嵌表达式中还可以调用方法,比如:
String s = STR."My blog is \{getMyBlog()}"; 

假设getMyBlog方法返回的内容为blog.didispace.com,那么最终s字符串结果为:My blog is blog.didispace.com

  1. 内嵌表达式中还可以访问对象的成员变量,比如:
User u = new User("didi", "blog.didispace.com"); // 构造函数参数为name属性和blog属性
String s = STR."\{u.name}的博客地地址为:+ \{u.blog}";

最终s字符串结果为:didi的博客地址为:blog.didispace.com

FMT模版处理器

除了STR模版处理器之外,Java中还提供了另外一个模版处理器:FMT。FMT模版处理器除了与STR模版处理器一样提供插值能力之外,还提供了左侧的格式化处理。下面通过例子来直接理解FMT的功能:

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 table = STR."""
    Description  Width  Height  Area
    \{zone[0].name}  \{zone[0].width}  \{zone[0].height}     \{zone[0].area()}
    \{zone[1].name}  \{zone[1].width}  \{zone[1].height}     \{zone[1].area()}
    \{zone[2].name}  \{zone[2].width}  \{zone[2].height}     \{zone[2].area()}
    Total \{zone[0].area() + zone[1].area() + zone[2].area()}
    """;

上面这块是由STR模版处理器组织字符串表格数据,从模版表达式来看是非常整齐的,但是由于模版中内嵌表达式的值长短不一,最终输出结果很有可能差强人意,比如STR模版处理器处理后的结果是这样的:

Description  Width  Height  Area
Alfa  17.8  31.4     558.92
Bravo  9.6  12.4     119.03999999999999
Charlie  7.1  11.23     79.733
Total 757.693

为了解决这个问题,就可以采用FMT模版处理器,在每一列左侧定义格式

String table = 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 21中推出的String Templates特性还有很多高级能力,比如:自定义模版处理器等。因为该特性还处于Preview阶段,所以DD也还没有深入研究,仅尝鲜了一下基本功能,如果您对其他高级能力感兴趣,也可以通过官网学习。等该功能正式发布之后,我会在 Java新特性专栏 中更新解读所有内容,欢迎关注与收藏。

欢迎关注我的公众号:程序猿DD。第一时间了解前沿行业消息、分享深度技术干货、获取优质学习资源


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK