来自Perl,我肯定错过了在源代码中创建多行字符串的“here-document”方法:
$string = <<"EOF" # create a three-line string
text
text
text
EOF
在Java中,当我从头开始连接多行字符串时,我必须在每一行上使用繁琐的引号和加号。
有什么更好的选择吗?在属性文件中定义我的字符串?
编辑:有两个答案说StringBuilder.append()比加号更可取。谁能详细解释一下他们为什么这么想?在我看来,这一点也不可取。我正在寻找一种方法来解决多行字符串不是一级语言结构这一事实,这意味着我绝对不想用方法调用取代一级语言结构(字符串连接与加号)。
编辑:为了进一步澄清我的问题,我根本不关心性能。我关心的是可维护性和设计问题。
后期模型JAVA对+和常量字符串进行了优化,在幕后使用了StringBuffer,所以你不想让它使你的代码变得混乱。
它指出了JAVA的一个疏忽,它不像ANSI C在双引号字符串之间只有空白的自动连接,例如:
const char usage = "\n"
"Usage: xxxx <options>\n"
"\n"
"Removes your options as designated by the required parameter <options>,\n"
"which must be one of the following strings:\n"
" love\n"
" sex\n"
" drugs\n"
" rockandroll\n"
"\n" ;
我想有一个多行字符数组常量,其中嵌入换行是光荣的,所以我可以在没有任何混乱的情况下呈现块,例如:
String Query = "
SELECT
some_column,
another column
FROM
one_table a
JOIN
another_table b
ON a.id = b.id
AND a.role_code = b.role_code
WHERE a.dept = 'sales'
AND b.sales_quote > 1000
Order BY 1, 2
" ;
要做到这一点,需要打败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
为了进一步澄清我的问题,我根本不关心性能。我关心的是可维护性和设计问题。
尽你所能让它清晰简单。
由于Java(还)不支持多行字符串,目前唯一的方法是使用前面提到的技术之一来破解它。我使用上面提到的一些技巧构建了下面的Python脚本:
import sys
import string
import os
print 'new String('
for line in sys.stdin:
one = string.replace(line, '"', '\\"').rstrip(os.linesep)
print ' + "' + one + ' "'
print ')'
把它放在一个名为javastringify.py的文件中,把你的字符串放在一个名为mystring.txt的文件中,然后像下面这样运行:
cat mystring.txt | python javastringify.py
然后,您可以复制输出并将其粘贴到编辑器中。
修改这需要处理任何特殊情况,但这是为我的需要。希望这能有所帮助!