来自Perl,我肯定错过了在源代码中创建多行字符串的“here-document”方法:

$string = <<"EOF"  # create a three-line string
text
text
text
EOF

在Java中,当我从头开始连接多行字符串时,我必须在每一行上使用繁琐的引号和加号。

有什么更好的选择吗?在属性文件中定义我的字符串?

编辑:有两个答案说StringBuilder.append()比加号更可取。谁能详细解释一下他们为什么这么想?在我看来,这一点也不可取。我正在寻找一种方法来解决多行字符串不是一级语言结构这一事实,这意味着我绝对不想用方法调用取代一级语言结构(字符串连接与加号)。

编辑:为了进一步澄清我的问题,我根本不关心性能。我关心的是可维护性和设计问题。


当前回答

遗憾的是,Java没有多行字符串字面量。您要么必须连接字符串字面量(使用+或StringBuilder是最常见的两种方法),要么从单独的文件中读取字符串。

对于大的多行字符串文字,我倾向于使用一个单独的文件,并使用getResourceAsStream() (Class类的一个方法)读取它。这使得查找文件变得很容易,因为您不必担心当前目录与代码安装的位置。它还使打包更容易,因为您实际上可以将文件存储在jar文件中。

假设你在一个名为Foo的类中。就像这样做:

Reader r = new InputStreamReader(Foo.class.getResourceAsStream("filename"), "UTF-8");
String s = Utils.readAll(r);

另一个烦恼是Java没有标准的“将这个Reader中的所有文本读入字符串”方法。写起来很简单:

public static String readAll(Reader input) {
    StringBuilder sb = new StringBuilder();
    char[] buffer = new char[4096];
    int charsRead;
    while ((charsRead = input.read(buffer)) >= 0) {
        sb.append(buffer, 0, charsRead);
    }
    input.close();
    return sb.toString();
}

其他回答

这看起来可能有点疯狂,但由于这里文档是单行声明的语法糖,并转义了换行符,因此可以为Java文件编写预处理程序,在预处理期间将这里文档更改为单行。

这需要在编译阶段(对于ant/maven构建)之前为预处理文件编写适当的插件,并为IDE编写插件。

从意识形态的观点来看,它与f.g.没有什么不同。“泛型”,这也是一种预处理的语法加糖铸造。

然而,这是一个大量的工作,所以我会在你的地方只使用.properties文件。

我至少看到了一种应该避免使用外部文件处理长字符串的情况:如果这些长字符串是单元测试文件中的预期值,因为我认为测试应该始终以一种不依赖任何外部资源的方式编写。


注意:这个答案适用于Java 14及以上版本。

Java 15引入了文本块(多行文字)。详情请看这个答案。


听起来像是要做一个多行文字,这在Java中是不存在的。

你最好的选择是用+ d组合的字符串。人们提到的一些其他选项(StringBuilder, String。format, String.join)只有当你从一个字符串数组开始时才更可取。

考虑一下:

String s = "It was the best of times, it was the worst of times,\n"
         + "it was the age of wisdom, it was the age of foolishness,\n"
         + "it was the epoch of belief, it was the epoch of incredulity,\n"
         + "it was the season of Light, it was the season of Darkness,\n"
         + "it was the spring of hope, it was the winter of despair,\n"
         + "we had everything before us, we had nothing before us";

与StringBuilder:

String s = new StringBuilder()
           .append("It was the best of times, it was the worst of times,\n")
           .append("it was the age of wisdom, it was the age of foolishness,\n")
           .append("it was the epoch of belief, it was the epoch of incredulity,\n")
           .append("it was the season of Light, it was the season of Darkness,\n")
           .append("it was the spring of hope, it was the winter of despair,\n")
           .append("we had everything before us, we had nothing before us")
           .toString();

与String.format ():

String s = String.format("%s\n%s\n%s\n%s\n%s\n%s"
         , "It was the best of times, it was the worst of times,"
         , "it was the age of wisdom, it was the age of foolishness,"
         , "it was the epoch of belief, it was the epoch of incredulity,"
         , "it was the season of Light, it was the season of Darkness,"
         , "it was the spring of hope, it was the winter of despair,"
         , "we had everything before us, we had nothing before us"
);

相对于Java8 String.join():

String s = String.join("\n"
         , "It was the best of times, it was the worst of times,"
         , "it was the age of wisdom, it was the age of foolishness,"
         , "it was the epoch of belief, it was the epoch of incredulity,"
         , "it was the season of Light, it was the season of Darkness,"
         , "it was the spring of hope, it was the winter of despair,"
         , "we had everything before us, we had nothing before us"
);

如果您想在特定的系统中使用换行符,您要么需要使用system . lineseparator(),要么可以在String.format中使用%n。

另一种选择是将资源放在文本文件中,只读取该文件的内容。对于非常大的字符串,这将是可取的,以避免不必要地膨胀您的类文件。

我所知道的唯一方法是用加号连接多行

String newline = System.getProperty ("line.separator");
string1 + newline + string2 + newline + string3

但是,最好的替代方法是使用String.format

String multilineString = String.format("%s\n%s\n%s\n",line1,line2,line3);