• Java 8之后的那些新特性(二):文本块 Text Blocks


    继续聊Java 8之后的新特性,这周我讲下Text Blocks这个特性。

    Text Blocks最开始是个JDK 14引进的,当时为预览版功能,在JDK 15中被正式确定。

    这意味着如果你想使用这个功能,得考虑使用最新的LTS JDK 17才行。

    这篇文章是Java 8之后的新特性系列的第二篇,本系列其它文章为:

    1. Java 8之后的那些新特性(一):局部变量var

    文本的困扰

    在Java过往的编码中,有一个问题始终不太好处理,这个问题就是:

    如何方便的处理多行字符块

    Java语言中并未提供任何能方便处理多行字符串的特性,导致在一些需要多行字符串的编码过程中,实现起来非常不简洁。如果多行字符串中还需要动态变量,就更麻烦了。

    过往的实现方式无非是以下两种:

    • 使用"\n","+"等方式来处理
    • 不使用多行,整成一行来处理

    举个实际例子来说明下:

    我通常在写REST层单元测试时,需要构建JSON字符串,比如在API请求中,类似的需求是很正常的吧。

    在单元测试中,比如需要构建如下JSON数据,并且其中一些字段希望是随机生成的(更有利于测试)

    [
      {
        "itemNo": "itemNo",
        "contractQuotation": {
          "id": "id"
        },
        "partNo": "partNo",
        "name": "name",
        "count": 1,
        "price": 103
      }
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在Java中,这个多行字符串在单元测试中构建数据时,我过往是这样写的:

    private String createItemJson(Long contractQuotationId) {
            return "[{\"itemNo\":\"itemNO_" + UUID.randomUUID().toString() + "\",\"contractQuotation\":{\"id\":" + contractQuotationId + "},\"partNo\":\"partNo_1\",\"name\":\"name_1\",\"count\":1,\"price\":109}]";
        }
    
    • 1
    • 2
    • 3

    当然,你也可以使用"\n","+"的方式写成多行。但无论哪个方式肯定是没有任何简洁性和优雅可言的吧。

    这就是Java中的多行字符串的困境。

    对比与伤害

    没有对比,就没有伤害

    我们还是来看下其它语言是怎么处理这样的场景的吧。

    我用Kotlin与TypeScript两种语言来重写上面这个方法,这样大家就有直观的感受了。

    Kotlin

        fun createItemJson(contractQuotationId:Long):String{
            return """
                [
                  {
                    "itemNo": ${UUID.randomUUID()},
                    "contractQuotation": {
                      "id": $contractQuotationId
                    },
                    "partNo": "partNo_1",
                    "name": "name_1",
                    "count": 1,
                    "price": 109
                  }
                ]
            """.trimIndent()
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    TypeScript

        public createItemJson(contractQuotationId:number):string {
            return `
            [
                {
                  "itemNo": `+this.randomString()+`,
                  "contractQuotation": {
                    "id": `+contractQuotationId+`
                  },
                  "partNo": "partNo_1",
                  "name": "name_1",
                  "count": 1,
                  "price": 103
                }
            `
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    代码胜过一切了吧,相比较下来,简洁与优雅不在同一个层次上吧。

    Text Blocks

    这就是Java的Text Blocks的想要解决的问题。

    Java的Text Blocks完美的借鉴了其它语言在支持多行文本上的做法,其实现几乎与Kotlin看不出太大的区别。

    如果我们用Java的Text Blocks来重写这个方法,那么你会看到效果是:

        private String createItemJson(Long contractQuotationId) {
            var json = """
                    [
                      {
                        "itemNo": %s,
                        "contractQuotation": {
                          "id": %s
                        },
                        "partNo": "partNo",
                        "name": "name",
                        "count": 1,
                        "price": 103
                      }
                    ]
                    """;
            return String.format(json,UUID.randomUUID().toString(),contractQuotationId);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    总体来说,这个特性和其它语言表现差不太多。

    有点区别的是:

    • Java字符中没有支持变量的特性,所以上述中一些变量只能考虑使用**%s**这样的变通的方式实现

    更多

    当然,这个特性并不是只是简单的支持多行文本这么个程度,细究起来,里面还有挺多细节可以关注。

    比如

    • 最后一行究竟会不会换行?
    • 多行字符串的最终显示前面的空格长度是怎么控制
    • 特殊的字符有没有需要特别处理的?

    关于这些,建议阅读Java Oracle官方的文档。我有一个建议需要重复一次,那就是:

    对于任何语言或者框架,最先需要阅读的文档一定是官网

    在我的《追求高效的程序员》这个系列中,有一个章节专门说如何高效的学习,也提及了这一点。官网的文档永远是最新的,最全的。

    至于额外的一些博客,教程或书本,都要排在官网之后,有需要时再参考与补充。

    这个Text Blocks的特性就聊到这里了,是不是虽然简单但非常实用呢。

    最后

    有时候,我们并不能随心所欲的决定一些事情,所以我会寻找另外的方案来改善它,你想知道我是如何处理上面的这种情况么?

        private String buildEmployeeJsonWithUpdate(EmployeeDto dto,String name){
            var jsonObject = new JsonObject();
            jsonObject.addProperty("name",name);
            jsonObject.addProperty("email",dto.getEmail());
            jsonObject.addProperty("phone",dto.getPhone());
            return jsonObject.toString();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    我选择使用JsonObject来构建JSON字符,至少相比起来,相对是一种也不算很差的实现方式了吧。

    如果你有更优雅的实现方式,请务必告知。


    下周我继续和大家聊Java 8之后的新特性。

  • 相关阅读:
    技术面试(一)认识技术面试
    C Primer Plus(6) 中文版 第5章 运算符、表达式和语句 5.5 类型转换
    MYSQL中varchar和TEXT
    Linux权限管理【理论讲解+实操演示】
    Doris通过ODBC驱动导入外部表数据
    淀粉2207空头逼仓,玉米认沽大涨1-6倍,淀粉09-01正套2022.6.30
    调研capacitor兼容openharmony平台可行性
    领导都在用的Python有多厉害
    touchGFX综合学习十四、基于cubeMX、正点原子H750开发版、RGB4.3寸屏移植touchGFX完整教程+工程(二)
    Android studio 使用opencl库(realme 手机)
  • 原文地址:https://blog.csdn.net/taoofcode/article/details/125916409