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

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

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

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

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

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


当前回答

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

其他回答

你可以使用scala-code,它与java兼容,并且允许用""" "括起来的多行字符串:

package foobar
object SWrap {
  def bar = """John said: "This is
  a test
  a bloody test,
  my dear." and closed the door.""" 
}

(注意字符串内的引号)和来自java:

String s2 = foobar.SWrap.bar ();

这样是否更舒服?

另一种方法,如果你经常处理长文本,应该放在你的源代码中,可能是一个脚本,它从外部文件中获取文本,并将其包装为一个多行java- string,像这样:

sed '1s/^/String s = \"/;2,$s/^/\t+ "/;2,$s/$/"/' file > file.java

这样你就可以很容易地复制粘贴到你的源代码中。

遗憾的是,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();
}

如果你像我一样喜欢谷歌的番石榴,它可以提供一个相当干净的表示和一个很好的,简单的方法来不硬编码你的换行符:

String out = Joiner.on(newline).join(ImmutableList.of(
    "line1",
    "line2",
    "line3"));

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

加号被转换为StringBuilder。除非两个字符串都是常量,以便编译器可以在编译时将它们组合在一起。至少,Sun的编译器是这样的,我怀疑大多数(如果不是所有)其他编译器也会这样做。

So:

String a="Hello";
String b="Goodbye";
String c=a+b;

通常生成完全相同的代码:

String a="Hello";
String b="Goodbye":
StringBuilder temp=new StringBuilder();
temp.append(a).append(b);
String c=temp.toString();

另一方面:

String c="Hello"+"Goodbye";

等于:

String c="HelloGoodbye";

也就是说,为了可读性,在多行中使用加号将字符串字面量分开并不会受到惩罚。