动机
在Java在代码中嵌入 HTML, XML, SQL, 或 JSON等多行字符串时,我们需要使用换行符"\n"或者字符串拼接"+"操作符以及转义符,可读性大大降低。或者使用StringBuilder优化长字符串拼接操作。
示例:
package com.renzhikeji.demo;
/**
* @author 认知科技技术团队
* 微信公众号:认知科技技术团队
*/
public class Demo {
public static void main(String[] args) {
String query = "SELECT \"EMP_ID\", \"LAST_NAME\" FROM \"EMPLOYEE_TB\"\n" +
"WHERE \"CITY\" = 'INDIANAPOLIS'\n" +
"ORDER BY \"EMP_ID\", \"LAST_NAME\";\n";
System.out.println(query);
}
}
Text Blocks(文本块)语法
文本块是一个多行字符串文字,它避免了大多数转义序列的需要,以可预测的方式自动格式化字符串,并在需要时让开发人员控制格式。
文本块以三个双引号字符 ( """)开始,以三个双引号字符 ( """)结束,需要跨行。
示例:
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
输出:
文本块可以表示空字符串,但不建议这样做,因为它需要两行代码:
String query = """
""";
否则会编译报错:
错误示例:
String query = """ """;
我们可以对待Text Blocks像以往的字符串一样,可以使用字符串拼接操作符或StringBuilder:
示例:
package com.renzhikeji.demo;
/**
* @author 认知科技技术团队
* 微信公众号:认知科技技术团队
*/
public class Demo {
public static void main(String[] args) {
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
String json = """
{
"name": "John Doe",
"age": 45,
"address": "Doe Street, 23, Java Town"
}
""";
{
System.out.println("............+ 操作......................");
System.out.println(query + json);
}
{
System.out.println("..........StringBuilder 操作......................");
StringBuilder sbr = new StringBuilder();
sbr.append(json).append("\n").append(query);
System.out.println(sbr);
}
}
}
输出:
Text Blocks(文本块)语法原理-编译时处理
文本块是类型String的常量表达式,就像字符串字面值一样。但是,与字符串字符串字面值不同,文本块的内容由 Java 编译器分三个不同的步骤处理:
1、内容中的行终止符被翻译为 LF ( \u000A)。
2、为匹配 Java 源代码的缩进而引入的空白被删除。
3、内容中的转义序列被解释
处理后的内容作为常量池中的CONSTANT_String_info条目记录在类文件中,就像字符串文字的字符一样。类文件不记录CONSTANT_String_info条目是从文本块还是字符串字面值派生的。
在运行时,文本块被计算为字符串的实例,就像字符串文本一样。从文本块派生的字符串实例与从字符串文本派生的实例无法区分。具有相同处理内容的两个文本块将引用相同的字符串实例,这与字符串文本一样。
我们可以翻译验证一下:
package com.renzhikeji.demo;
/**
* @author 认知科技技术团队
* 微信公众号:认知科技技术团队
*/
public class Demo {
public static void main(String[] args) {
String json = """
{
"name": "John Doe",
"age": 45,
"address": "Doe Street, 23, Java Town"
}
""";
System.out.println(json);
}
}
javap -c -v target/classes/com/renzhikeji/demo/Demo.class
反编译后:
Constant pool段,#7、#8 表明Text Blocks其实就是一个字符面值,只是个语法糖。