原始字符串文字没有进入Java 12。Java 13中提供了类似的功能,而不是预览功能 - 文本块。有关详细信息,请参阅下面的帖子。
在从Java 12中删除类似功能之后,Java 13最终支持多行字符串文字。
Raw String 在 Java 12 的最终版本发布之前被删除,现在被认为已经过时了。
我们当然感到失望的是,这意味着这个功能需要稍长时间才能成为语言,但我们认为这是最好的选择。
虽然我们可以预期,对于任何语言功能,都会有一个非常重要的“我会更喜欢它不同”的反馈,在回顾我们收到的反馈时,我不再相信我们已经达到了正确的设置在复杂性和表现力之间进行权衡,或者我们已经探索了足够的设计空间,以确信当前的设计是我们能做的最好的。通过撤销,我们可以继续改进设计,探索更多选项,并瞄准实际满足预览功能流程(JEP 12)要求的预览。
目前(Java之前的版本12),Java中的字符串文字在许多情况下不必要地难以处理并且具有一些限制。
首先,Java不支持多行字符串。如果希望字符串跨越多行,则必须连接多个字符串:
String myString = "This is my string" +
" which I want to be " +
"on multiple lines.";
但它变得更糟。如果希望字符串实际包含新行,则需要\n
在每行后插入。
String myString = "This is my string\n" +
" which I want to be \n" +
"on multiple lines.";
使用反斜杠转义特殊字符(如换行符)\
。这对于双引号是必要的,"
因为它们将终止字符串以及反斜杠\
字符,因为它将指示转义字符。除此之外,java中有一大堆转义序列:
序列 | 用法 |
---|---|
\ t | 标签 |
\ b | 退格(删除上一个字符) |
\ n | 新队 |
\ r | 回程 |
\F | 表格饲料 |
’ | 单引号字符 |
\” | 双引号字符 |
\ | 反斜杠字符 |
字符串文字通常难以阅读,因为它们受到转义序列的困扰:
String myPath = "Open \"C:\\Program Files\\Java\\jdk1.8.0_151\"";
对于正则表达式来说尤其糟糕,正则表达式可能会使用大量的反斜杠,因此很难读取。
事实证明,其他JVM语言已经解决了多行字符串和转义序列的可读性问题。它们被称为Raw Strings。它们可以跨越多行而不连接,并且它们不使用转义序列。您可以直接使用反斜杠或双引号。例如,在Kotlin中,除了常规字符串文字之外,您还可以使用带有三个双引号的Raw Strings """
而不是一个。
val text = """
This is my string
which I want to be
on multiple lines.
It can contain backslash \
Or even double-quotes "
"""
在JVM上,Groovy和Scala也支持使用原始字符串"""
。Java就像通常迟到一样(类似于引入JShell REPL),现在只在版本12中介绍了其他JVM和非JVM语言中已经很常见的内容。
在Java 12中,新功能之一将是JEP 326:Raw String Literals。与使用"""
Java的Kotlin,Groovy或Python 决定使用反引号```表示法不同,后者当前由Javascript或Go使用。
String rawString = `This is my string
which I want to be
on multiple lines.
It can contain backslash \
Or even quotes "`;
但与javascript不同,字符串内的反引号不需要转义。相反,您可以使用多个反引号来启动字符串,然后使用相同数量的反引号来结束它:
`This uses single backtick`
``This can contain backtick `, see?``
```Can use any number of backticks```
无论您使用多少反引号或者使用原始或原始字符串文字,结果.class
文件都是相同的,并且两个文字都会生成java.lang.String
。
多行原始字符串的一个问题是它们将每行上的所有字符解释为字符串的一部分。想象一下下面的代码。
public class Main {
public static void main(String[] args) {
String myString =
`This is my string
which I want to be
on multiple lines.`;
System.out.println(myString);
}
}
原始字符串的每一行在左边都包含一些空格作为缩进,因此代码格式很好 - 4个空格缩进,因为它在一个类中,另外4个因为它在main方法中。如果你运行它,你会看到:
This is my string
which I want to be
on multiple lines.
该字符串包含缩进,只能将代码格式化为更易读,但它不是字符串的一部分。
快速解决方法是删除缩进,但很难理解:
public class Main {
public static void main(String[] args) {
String myString =`This is my string
which I want to be
on multiple lines.`;
System.out.println(myString);
}
}
实际上,String
该类中有几种新方法,可用于处理缩进。
该方法align()
修剪字符串的水平和垂直缩进,并保持线的相对缩进。
public class Main {
public static void main(String[] args) {
String myString = `
This is my string
which I want to be
on multiple lines.
Note that after alignment,
only relative indentation is preserved.
`.align();
System.out.println(myString);
}
}
对齐后,输出将为:
This is my string
which I want to be
on multiple lines.
Note that after alignment,
only relative indentation is preserved.
如果您不想修剪空白但只增加或减少对齐,则可以使用 String.indent(numberOfSpaces)
// Increase existing indentation of each line by 2
myString.indent(2);
// Decrease existing indentation of each line by 2
myString.indent(-2);
作为简写,如果align()
使用整数参数而不是零参数调用,它将首先对齐,然后按给定的数字缩进:
// Align and then increase existing indentation of each line by 2
myString.align(2);
目前支持Raw String文字的其他语言通常也支持字符串插值。它基本上是一个花哨的名称,用字符串替换字符串中的变量占位符,例如:
val name = "John"
println("Hi, my name is ${name}.")
不幸的是,这在Java中仍然是不可能的,甚至不是Java 12. JEP 326甚至明确指出这不是本提案的一部分。但是,将来某些其他提案可能会引入它。
好消息是,自2018.3版以来,IDEA已经支持Raw String Literals。
您可以将旧的字符串文字转换为原始字符串,反之亦然。IDEA将为您处理转义序列转换和拆分为多行。
IDEA还可以检测您是否不必要地使用过多的反引号,并且能够为您移除多余的反引号。
除此之外,它现在还支持Raw String Literals中的拼写检查或正则表达式检测等操作。您可以在IntelliJ IDEA 2018.3中的预览原始字符串文字中阅读更多内容。
截至11/2018 Java 12尚未推出,但您已经可以下载JDK 12的早期版本,并为自己尝试Raw Strings。