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

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

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

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

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

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


当前回答

实际上,下面是我迄今为止见过的最干净的实现。它使用注释将注释转换为字符串变量…

/**
  <html>
    <head/>
    <body>
      <p>
        Hello<br/>
        Multiline<br/>
        World<br/>
      </p>
    </body>
  </html>
  */
  @Multiline
  private static String html;

因此,最终结果是变量html包含多行字符串。没有引号,没有加号,没有逗号,只有纯字符串。

该解决方案可在以下URL… http://www.adrianwalker.org/2011/12/java-multiline-string.html

希望有帮助!

其他回答

这是你不应该在不考虑它在做什么的情况下使用的东西。但对于一次性脚本,我已经成功地使用了这个方法:

例子:

    System.out.println(S(/*
This is a CRAZY " ' ' " multiline string with all sorts of strange 
   characters!
*/));

代码:

// From: http://blog.efftinge.de/2008/10/multi-line-string-literals-in-java.html
// Takes a comment (/**/) and turns everything inside the comment to a string that is returned from S()
public static String S() {
    StackTraceElement element = new RuntimeException().getStackTrace()[1];
    String name = element.getClassName().replace('.', '/') + ".java";
    StringBuilder sb = new StringBuilder();
    String line = null;
    InputStream in = classLoader.getResourceAsStream(name);
    String s = convertStreamToString(in, element.getLineNumber());
    return s.substring(s.indexOf("/*")+2, s.indexOf("*/"));
}

// From http://www.kodejava.org/examples/266.html
private static String convertStreamToString(InputStream is, int lineNum) {
    /*
     * To convert the InputStream to String we use the BufferedReader.readLine()
     * method. We iterate until the BufferedReader return null which means
     * there's no more data to read. Each line will appended to a StringBuilder
     * and returned as String.
     */
    BufferedReader reader = new BufferedReader(new InputStreamReader(is));
    StringBuilder sb = new StringBuilder();

    String line = null; int i = 1;
    try {
        while ((line = reader.readLine()) != null) {
            if (i++ >= lineNum) {
                sb.append(line + "\n");
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    return sb.toString();
}

如果你在属性文件中定义字符串,它看起来会更糟糕。IIRC,它看起来像:

string:text\u000atext\u000atext\u000a

一般来说,在源代码中不嵌入大字符串是一个合理的想法。您可能希望将它们作为资源加载,可能以XML或可读的文本格式加载。文本文件可以在运行时读取,也可以编译成Java源代码。如果你最终把它们放在源代码中,我建议把+放在前面,省略不必要的新行:

final String text = ""
    +"text "
    +"text "
    +"text"
;

如果你有新的行,你可能需要一些join或格式化方法:

final String text = join("\r\n"
    ,"text"
    ,"text"
    ,"text"
);

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

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

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

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

    import org.apache.commons.lang3.StringUtils;

    String multiline = StringUtils.join(new String[] {
        "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",
        }, "\n");

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