来自Perl,我肯定错过了在源代码中创建多行字符串的“here-document”方法:
$string = <<"EOF" # create a three-line string
text
text
text
EOF
在Java中,当我从头开始连接多行字符串时,我必须在每一行上使用繁琐的引号和加号。
有什么更好的选择吗?在属性文件中定义我的字符串?
编辑:有两个答案说StringBuilder.append()比加号更可取。谁能详细解释一下他们为什么这么想?在我看来,这一点也不可取。我正在寻找一种方法来解决多行字符串不是一级语言结构这一事实,这意味着我绝对不想用方法调用取代一级语言结构(字符串连接与加号)。
编辑:为了进一步澄清我的问题,我根本不关心性能。我关心的是可维护性和设计问题。
当我读到多行语法确实是为jdk7计划的(在java存在了多少年之后?)时,我有点恼火。有趣的是,甚至还没有readAll()函数用于读取文件的完整内容(仅从jdk7读取,啊啊),因此下面的代码读取单行。
/*
MakeMultiline v1.0 (2010) - Free to use and copy.
Small gadget to turn text blobs into one java string literal
(doing the split in lines, adding \n at each end and enclosing
in double quotes). Does escape quotes encountered in the text blob.
Useful for working around missing multiline string syntax in java
prior jdk7. Use with:
java MakeMultiline " "
or
java MakeMultiline " " mytextfile.txt
*/
import java.io.*;
class MakeMultiline {
public static void main(String[] args) {
try {
// args[0]: indent
// args[1]: filename to read (optional; stdin if not given)
// Beware the nmb of newlines at the end when using stdin!
String indent = (args.length > 0 ? args[0] : "");
FileReader fr = null; BufferedReader br;
if (args.length > 1)
{ fr = new FileReader(args[1]); br = new BufferedReader(fr); }
else
{ br = new BufferedReader(new InputStreamReader(System.in)); }
String s; String res = "";
while((s = br.readLine()) != null) {
if (res.length() > 0) res += " +\n";
res += indent + "\"" + s.replace("\"", "\\\"") + "\\n\"";
}
br.close(); if (fr != null) fr.close();
System.out.println(res + ";");
}
catch(Exception e) {
System.out.println("Exception: " + e);
}
}
}
这对我来说是最快的解决办法。(2010-01-27)
你可以使用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
这样你就可以很容易地复制粘贴到你的源代码中。
当使用一长串的+时,只会创建一个StringBuilder,除非在编译时确定String,在这种情况下不使用StringBuilder !
StringBuilder唯一更高效的情况是使用多个语句构造String。
String a = "a\n";
String b = "b\n";
String c = "c\n";
String d = "d\n";
String abcd = a + b + c + d;
System.out.println(abcd);
String abcd2 = "a\n" +
"b\n" +
"c\n" +
"d\n";
System.out.println(abcd2);
注意:只创建了一个StringBuilder。
Code:
0: ldc #2; //String a\n
2: astore_1
3: ldc #3; //String b\n
5: astore_2
6: ldc #4; //String c\n
8: astore_3
9: ldc #5; //String d\n
11: astore 4
13: new #6; //class java/lang/StringBuilder
16: dup
17: invokespecial #7; //Method java/lang/StringBuilder."<init>":()V
20: aload_1
21: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
24: aload_2
25: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
28: aload_3
29: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
32: aload 4
34: invokevirtual #8; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
37: invokevirtual #9; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
40: astore 5
42: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream;
45: aload 5
47: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
50: ldc #12; //String a\nb\nc\nd\n
52: astore 6
54: getstatic #10; //Field java/lang/System.out:Ljava/io/PrintStream;
57: aload 6
59: invokevirtual #11; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
62: return
为了进一步澄清我的问题,我根本不关心性能。我关心的是可维护性和设计问题。
尽你所能让它清晰简单。