Java多行字符串

ski*_*ppy 486 java string multiline

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

$string = <<"EOF"  # create a three-line string
text
text
text
EOF
Run Code Online (Sandbox Code Playgroud)

在Java中,我必须在每一行都有繁琐的引号和加号,因为我从头开始连接多行字符串.

有哪些更好的选择?在属性文件中定义我的字符串?

编辑:两个答案说StringBuilder.append()优于加号表示法.任何人都可以详细说明他们为什么这么认为?它看起来并不比我更好.我正在寻找一种方法,即多行字符串不是一流的语言结构,这意味着我绝对不希望用方法调用替换第一类语言结构(字符串连接加上).

编辑:为了进一步澄清我的问题,我根本不关心表现.我担心可维护性和设计问题.

Kip*_*Kip 459

听起来你想要做一个多线文字,这在Java中是不存在的.

你最好的选择就是成为一起的弦乐+.人们提到的其他一些选项(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";
Run Code Online (Sandbox Code Playgroud)

对比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();
Run Code Online (Sandbox Code Playgroud)

对比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"
);
Run Code Online (Sandbox Code Playgroud)

与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"
);
Run Code Online (Sandbox Code Playgroud)

如果您想为您的特定系统的换行,你要么需要使用System.lineSeparator(),也可以使用%nString.format.

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

  • 此外,第一个版本将由编译器自动连接,因为所有字符串在编译时都是已知的.即使在编译时不知道字符串,它也不比StringBuilder或String.format()慢.避免与+串联的唯一原因是你是在循环中进行连接. (242认同)
  • `String.format`版本的问题是你必须保持格式与行数同步. (21认同)
  • @BlessedGeek:手头的问题是关于Java语言中可用的选项.它没有提到任何关于进入字符串的数据类型.如果有更好的解决方案,那么您可以将其作为答案发布.听起来像[Josh Curren的解决方案](http://stackoverflow.com/a/878603/18511)会更适合您的情况.如果您对该语言不支持多行文字感到不安,那么抱怨它就是错误的地方. (20认同)
  • 这个答案对于手头的问题是一个非常不合适的解决方案.我们有2000行SAS宏或200行SQL查询,我们希望复制和粘贴.建议我们使用+""concat将这些多行文本转换为StringBuffer追加是荒谬的. (10认同)
  • 与其他两个示例相比,String.format效率不高 (4认同)
  • @TudorManole:每次在字符串上使用`+`运算符(不计算字符串常量)时,编译器会将其转换为三步过程:(1)创建一个新的StringBuilder对象,(2)将两个字符串附加到它上,以及(3)使用toString()将其转换回String.这不是你想在循环中做的事情.如果需要循环,通常首先要设置一个StringBuilder,然后在循环内向它追加().这样就只有一个对象,并没有完全复制.有关稍长的版本,请参阅/sf/answers/547338921/. (3认同)
  • 使用过 Perl,我了解提问者的要求。允许多行字符串而不必用 + 符号和引号将其弄乱的各种替代方法是什么。我使用了 adrianwalker 的注释。使用 concat 不能替代多行字符串。 (2认同)
  • 我曾经使用过“String+”版本一段时间(在了解到编译时它会变成单个字符串之后),但我总是在每行末尾有“+”。将“+”与“=”对齐后,看起来会干净很多。 (2认同)
  • @BlessedGeek如果你从另一个背景来到java,你可能很想知道java是否提供了这个功能.仅仅因为答案是"不"并不意味着答案是显而易见的 (2认同)
  • 比缺少多行字符串文字支持更令人吃惊的是缺少一个`StringBuilder.appendLine()`函数来处理`System.getProperty("line.separator")` (2认同)

Mon*_*nir 186

在Eclipse中,如果打开选项"粘贴到字符串文字时转义文本"(在"首选项">"Java">"编辑器">"键入"中)并在引号中粘贴多行字符串,它将自动添加"\n" +为您的所有行添加.

String str = "paste your text here";
Run Code Online (Sandbox Code Playgroud)

  • 当你粘贴到""时,intelij默认也会这样做 (14认同)

Pau*_*rie 113

Stephen Colebourne创建了一个在Java 7中添加多行字符串的提议.

此外,Groovy已经支持多行字符串.

  • 用于Java增强的Project Coin流程包括多行字符串http://mail.openjdk.java.net/pipermail/coin-dev/2009-February/000034.html.它被Oracle http://blogs.sun.com/darcy/entry/project_coin_final_five拒绝. (14认同)
  • 不幸的是,这似乎没有成为规范. (13认同)
  • 2012年的任何变化? (8认同)
  • 似乎,截至2018年1月,社区正在重新考虑多线串.http://openjdk.java.net/jeps/326 (8认同)
  • blogs.sun.com链接已损坏,但我认为内容现在位于https://blogs.oracle.com/darcy/entry/project_coin_final_five. (3认同)
  • @ShaneGannon如此艰难的决定接受这个有用且有争议的功能!:) (3认同)
  • 原始字符串文字 (JEP326) 已从最终 JDK12 中删除,但已创建另一个 JEP 以添加 ["Text blocks"](http://openjdk.java.net/jeps/8222530),可以在 JDK 中作为预览完成13 (2认同)
  • 这应该在现在处于预览版的 JDK13 中完成。https://openjdk.java.net/jeps/355 (2认同)

SRG*_*SRG 97

这是一个旧的线程,但是一个新的非常优雅的解决方案(只有4个可能有3个小缺点)是使用自定义注释.

检查:http://www.adrianwalker.org/2011/12/java-multiline-string.html

受这项工作启发的项目在GitHub上托管:

https://github.com/benelog/multiline

Java代码示例:

import org.adrianwalker.multilinestring.Multiline;
...
public final class MultilineStringUsage {

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

  public static void main(final String[] args) {
    System.out.println(html);
  }
}
Run Code Online (Sandbox Code Playgroud)

缺点是

  1. 您必须激活相应的(提供的)注释处理器.
  2. String变量不能定义为局部变量Check Raw String Literals项目,您可以在其中将变量定义为局部变量
  3. String不能包含其他变量,如Visual Basic .Net with XML literal(<%= variable %>):-)
  4. 字符串文字由JavaDoc注释(/**)分隔

您可能必须将Eclipse/Intellij-Idea配置为不自动重新格式化您的Javadoc注释.

有人可能会觉得这很奇怪(Javadoc的注释并不是为了嵌入除注释之外的任何东西),但由于Java中缺少多行字符串最终会让人烦恼,我觉得这是最差的解决方案.

  • 你可以在eclipse中完全做到这一点.@SRG上面发布的链接指向[此链接](https://github.com/benelog/multiline/wiki/Non-Maven-Java-project-with-Eclipse).如果你正在使用eclipse,那么一分钟的设置就可以了. (3认同)
  • 这可能是我见过的最大的黑客攻击.编辑:没关系......见Bob Albrights的回答. (3认同)
  • 我对这个项目进行了扩展,并创建了一个支持局部变量的新项目,[查看项目](https://github.com/mageddo/mageddo-projects/tree/master/raw-string-literals ) (3认同)

Jos*_*ren 60

另一个选项可能是将长字符串存储在外部文件中并将该文件读入字符串.

  • 你不应该仅仅因为它是多行而外化String.如果我有一个正则表达式,我想分成多行注释怎么办?它在Java中看起来很难看.C#的`@`语法更清晰. (62认同)
  • 究竟.大量文本不属于Java源代码; 使用适当格式的资源文件,通过调用Class.getResource(String)加载. (13认同)
  • 哇.在这个问题上,我无法相信C++实际上比Java更好!我喜欢多行字符串常量,并且在某些情况下它们属于源代码. (9认同)
  • Skiphoppy不想打扰处理文件的开销只是为了使用段落长度字符串常量.我一直在C++中使用多行字符串,嵌入在我的源代码中,我想要它们. (8认同)
  • 对!您也可以使用Locale + ResourceBundle轻松加载I18N文本,然后String.format()调用将解析"\n"作为换行符:)示例:String readyStr = String.parse(resourceBundle.getString("介绍")); (4认同)
  • 不要挑剔,但我认为C++在Java方面的优势通常是语言灵活性...... Java通常提供更严格的语言体验作为对初级开发人员的帮助,这本身就是一种优势. (3认同)
  • 任何常数越长/越复杂,它就越有可能被外部化。你编写的代码类型也会影响到——如果你正在编写一次性的、轻度维护的程序,那么嵌入你的常量会更清楚,对于企业代码,我听说它认为你应该将所有东西外部化(诚然,这已经有一段时间了)以前在一个不太敏捷的世界中)。由于我们谈论的是 java,因此我们倾向于企业/可维护端,因此您确实应该强烈考虑外部化任何多行字符串,或者尝试一种用于维护较轻的代码的语言(groovy?)。 (2认同)

Bob*_*ght 59

这是东西,你应该从来没有考虑它在做什么使用.但是对于一次性脚本我已经使用了这个非常成功:

例:

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

码:

// 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();
}
Run Code Online (Sandbox Code Playgroud)

  • 我可以想象当我尝试检查这样的事情时我的同事反应...... (23认同)
  • 需要使用最终二进制文件传送类的Java代码.嗯. (15认同)
  • +1.投票失败的人缺乏想象力.这是编写小实用程序,测试用例甚至是受控prod环境的有用构造.这是将java退出到ruby/python/etc或留在这里的差异制造者. (15认同)
  • “S()”方法中的声明“StringBuilder sb = new StringBuilder();”和“String line = null;”已完全过时。此外,当“readLine()”循环遇到包含“*/”的第一行时停止,它会更有效 (2认同)

icz*_*cza 50

String.join

Java 8添加了一个新的静态方法,java.lang.String它提供了一个更好的替代方案:

String.join( CharSequence delimiter , CharSequence... elements )

使用它:

String s = String.join(
    System.getProperty("line.separator"),
    "First line.",
    "Second line.",
    "The rest.",
    "And the last!"
);
Run Code Online (Sandbox Code Playgroud)

  • 干净整洁的解决方案!不依赖于IDE和预处理器!不需要手动""\n"`,并且知道可移植性! (3认同)
  • @dmitry 现在已经有了。然而,一个很大的问题是使用 System.getProperty("line.separator") 是提高了可移植性还是降低了可移植性。Java 语言设计者决定始终生成相同的字符串,无论代码在何处运行,换句话说,始终仅使用“\n”。为了在旧版本中实现相同的目的,诸如“String.join(…)”之类的黑客从来没有必要,““第一行。\ n”+“第二行。\ n”+“其余的。\ n”+“和最后一个!\n"` 完成了这项工作,并且可以在将文本粘贴到字符串时由 IDE 自动生成... (2认同)

Vla*_*cea 25

Java 13 及更高版本

Java 现在通过Text Blocks支持多行字符串。在 Java 13 和 14 中,此功能要求您––enable–preview在构建和运行项目时设置该选项。在 Java 15 及更高版本中,不再需要此选项,因为文本块已成为标准功能。查看官方的文本块程序员指南以获取更多详细信息。

现在,在 Java 13 之前,这是您编写查询的方式:

List<Tuple> posts = entityManager
.createNativeQuery(
    "SELECT *\n" +
    "FROM (\n" +
    "    SELECT *,\n" +
    "           dense_rank() OVER (\n" +
    "               ORDER BY \"p.created_on\", \"p.id\"\n" +
    "           ) rank\n" +
    "    FROM (\n" +
    "        SELECT p.id AS \"p.id\",\n" +
    "               p.created_on AS \"p.created_on\",\n" +
    "               p.title AS \"p.title\",\n" +
    "               pc.id as \"pc.id\",\n" +
    "               pc.created_on AS \"pc.created_on\",\n" +
    "               pc.review AS \"pc.review\",\n" +
    "               pc.post_id AS \"pc.post_id\"\n" +
    "        FROM post p\n" +
    "        LEFT JOIN post_comment pc ON p.id = pc.post_id\n" +
    "        WHERE p.title LIKE :titlePattern\n" +
    "        ORDER BY p.created_on\n" +
    "    ) p_pc\n" +
    ") p_pc_r\n" +
    "WHERE p_pc_r.rank <= :rank\n",
    Tuple.class)
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", 5)
.getResultList();
Run Code Online (Sandbox Code Playgroud)

感谢 Java 13 文本块,您可以按如下方式重写此查询:

List<Tuple> posts = entityManager
.createNativeQuery("""
    SELECT *
    FROM (
        SELECT *,
               dense_rank() OVER (
                   ORDER BY "p.created_on", "p.id"
               ) rank
        FROM (
            SELECT p.id AS "p.id",
                   p.created_on AS "p.created_on",
                   p.title AS "p.title",
                   pc.id as "pc.id",
                   pc.created_on AS "pc.created_on",
                   pc.review AS "pc.review",
                   pc.post_id AS "pc.post_id"
            FROM post p
            LEFT JOIN post_comment pc ON p.id = pc.post_id
            WHERE p.title LIKE :titlePattern
            ORDER BY p.created_on
        ) p_pc
    ) p_pc_r
    WHERE p_pc_r.rank <= :rank
    """,
    Tuple.class)
.setParameter("titlePattern", "High-Performance Java Persistence %")
.setParameter("rank", 5)
.getResultList();
Run Code Online (Sandbox Code Playgroud)

更具可读性,对吧?

IDE支持

IntelliJ IDEA 支持将旧的String连接块转换为新的多行String格式:

IntelliJ IDEA 文本块支持

JSON、HTML、XML

多行在String编写 JSON、HTML 或 XML 时特别有用。

考虑这个使用String连接来构建 JSON 字符串文字的示例:

entityManager.persist(
    new Book()
    .setId(1L)
    .setIsbn("978-9730228236")
    .setProperties(
        "{" +
        "   \"title\": \"High-Performance Java Persistence\"," +
        "   \"author\": \"Vlad Mihalcea\"," +
        "   \"publisher\": \"Amazon\"," +
        "   \"price\": 44.99," +
        "   \"reviews\": [" +
        "       {" +
        "           \"reviewer\": \"Cristiano\", " +
        "           \"review\": \"Excellent book to understand Java Persistence\", " +
        "           \"date\": \"2017-11-14\", " +
        "           \"rating\": 5" +
        "       }," +
        "       {" +
        "           \"reviewer\": \"T.W\", " +
        "           \"review\": \"The best JPA ORM book out there\", " +
        "           \"date\": \"2019-01-27\", " +
        "           \"rating\": 5" +
        "       }," +
        "       {" +
        "           \"reviewer\": \"Shaikh\", " +
        "           \"review\": \"The most informative book\", " +
        "           \"date\": \"2016-12-24\", " +
        "           \"rating\": 4" +
        "       }" +
        "   ]" +
        "}"
    )
);
Run Code Online (Sandbox Code Playgroud)

由于转义字符以及大量双引号和加号,您几乎无法读取 JSON。

使用 Java 文本块,JSON 对象可以这样编写:

entityManager.persist(
    new Book()
    .setId(1L)
    .setIsbn("978-9730228236")
    .setProperties("""
        {
           "title": "High-Performance Java Persistence",
           "author": "Vlad Mihalcea",
           "publisher": "Amazon",
           "price": 44.99,
           "reviews": [
               {
                   "reviewer": "Cristiano",
                   "review": "Excellent book to understand Java Persistence",
                   "date": "2017-11-14",
                   "rating": 5
               },
               {
                   "reviewer": "T.W",
                   "review": "The best JPA ORM book out there",
                   "date": "2019-01-27",
                   "rating": 5
               },
               {
                   "reviewer": "Shaikh",
                   "review": "The most informative book",
                   "date": "2016-12-24",
                   "rating": 4
               }
           ]
        }
        """
    )
);
Run Code Online (Sandbox Code Playgroud)

自从我在 2004 年使用 C# 以来,我一直想在 Java 中拥有这个功能,现在我们终于有了它。


Tom*_*ine 19

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

string:text\u000atext\u000atext\u000a
Run Code Online (Sandbox Code Playgroud)

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

final String text = ""
    +"text "
    +"text "
    +"text"
;
Run Code Online (Sandbox Code Playgroud)

如果您有新行,您可能需要一些连接或格式化方法:

final String text = join("\r\n"
    ,"text"
    ,"text"
    ,"text"
);
Run Code Online (Sandbox Code Playgroud)


Jay*_*Jay 17

将两个字符串转换为StringBuilder.append,除非两个字符串都是常量,因此编译器可以在编译时将它们组合在一起.至少,这就是Sun编译器中的情况,如果不是所有其他编译器都会这样做,我会怀疑大多数编译器.

所以:

String a="Hello";
String b="Goodbye";
String c=a+b;
Run Code Online (Sandbox Code Playgroud)

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

String a="Hello";
String b="Goodbye":
StringBuilder temp=new StringBuilder();
temp.append(a).append(b);
String c=temp.toString();
Run Code Online (Sandbox Code Playgroud)

另一方面:

String c="Hello"+"Goodbye";
Run Code Online (Sandbox Code Playgroud)

是相同的:

String c="HelloGoodbye";
Run Code Online (Sandbox Code Playgroud)

也就是说,在多行中打破你的字符串文字没有任何惩罚,加号为可读性.

  • 在技​​术上,在你的第一个例子中它产生了更像的东西:String c = new StringBuilder().append(a).append(b).toString(); 区别在于临时字符串构建器超出范围并且在String c = ...行之后立即有资格进行垃圾收集,而"temp"字符串构建器将保持更长时间. (4认同)

alo*_*ale 16

JEP 326:Raw String Literals将实现多行字符串,因此您可以编写如下内容:

String s = """
    text
    text
    text
  """;
Run Code Online (Sandbox Code Playgroud)

  • 他们放弃了这种支持 (2认同)
  • 文本块现在是 Java 13 的一部分。 (2认同)

nur*_*tin 14

在IntelliJ IDE中,您只需键入:

""
Run Code Online (Sandbox Code Playgroud)

然后将光标放在引号内并粘贴您的字符串.IDE将它扩展为多个连接行.


Lau*_*ves 11

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

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

假设你在一个名为Foo的类中.做这样的事情:

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

另一个烦恼是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();
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*Tom 10

String newline = System.getProperty ("line.separator");
string1 + newline + string2 + newline + string3
Run Code Online (Sandbox Code Playgroud)

但是,最好的选择是使用String.format

String multilineString = String.format("%s\n%s\n%s\n",line1,line2,line3);
Run Code Online (Sandbox Code Playgroud)

  • StringBuilder如何不那么恼人和不可读? (16认同)
  • 用一个六个字符的方法名称和括号替换一个加号对我来说看起来不那么可读,尽管显然你并不是唯一一个这样想的人.但它不会删除引号.他们还在那里. (3认同)
  • Stringbuilder示例至少是不可读的.另外,不要忘记"\n"并不总是换行符,但对于linux和unix机器来说这很好. (2认同)

use*_*own 9

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

package foobar
object SWrap {
  def bar = """John said: "This is
  a test
  a bloody test,
  my dear." and closed the door.""" 
}
Run Code Online (Sandbox Code Playgroud)

(注意字符串中的引号)和java:

String s2 = foobar.SWrap.bar ();
Run Code Online (Sandbox Code Playgroud)

这是否更舒服......?

另一种方法,如果你经常处理长文本,它应放在你的源代码中,可能是一个脚本,它从外部文件获取文本,并将其作为multiline-java-String包装,如下所示:

sed '1s/^/String s = \"/;2,$s/^/\t+ "/;2,$s/$/"/' file > file.java
Run Code Online (Sandbox Code Playgroud)

这样您就可以轻松地将其剪切并粘贴到源中.


sco*_*awg 9

由于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 ')'
Run Code Online (Sandbox Code Playgroud)

将它放在名为javastringify.py的文件中,并将您的字符串放在mystring.txt文件中,并按如下方式运行:

cat mystring.txt | python javastringify.py
Run Code Online (Sandbox Code Playgroud)

然后,您可以复制输出并将其粘贴到编辑器中.

根据需要修改它以处理任何特殊情况,但这适用于我的需要.希望这可以帮助!


use*_*579 8

您可以使用单独的方法连接附加内容,例如:

public static String multilineString(String... lines){
   StringBuilder sb = new StringBuilder();
   for(String s : lines){
     sb.append(s);
     sb.append ('\n');
   }
   return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

无论哪种方式,更喜欢StringBuilder加号表示法.

  • 效率,或者说是经常被误导的尝试. (10认同)
  • 为什么我更喜欢StringBuilder加号? (5认同)
  • 只有当编译器无法做到这一点.对于文字和常量,如果使用加号,则串联在编译时完成.使用StringBuilder强制它在运行时发生,因此它不仅工作量更大,而且速度更慢. (4认同)
  • 我认为,效率的尝试基于以下事实:Java编译器使用StringBuilder(1.5版之前的编译器中的StringBuffer)实现字符串连接运算符.有一篇古老但却众所周知的文章指出,在某些情况下使用StringBuffer(或现在的StringBuilder)会有性能优势.这是链接:http://java.sun.com/developer/JDCTechTips/2002/tt0305.html (2认同)

Leo*_*Leo 7

请参阅Java Stringfier.如果需要,将文本转换为StringBuilder java块转义.


Myk*_*ych 7

    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");
Run Code Online (Sandbox Code Playgroud)


Rod*_*ati 7

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

/**
  <html>
    <head/>
    <body>
      <p>
        Hello<br/>
        Multiline<br/>
        World<br/>
      </p>
    </body>
  </html>
  */
  @Multiline
  private static String html;
Run Code Online (Sandbox Code Playgroud)

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

此解决方案可从以下URL获得... http://www.adrianwalker.org/2011/12/java-multiline-string.html

希望有所帮助!


Bal*_*usC 6

我没有看到答案的替代方案是java.io.PrintWriter.

StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter);
writer.println("It was the best of times, it was the worst of times");
writer.println("it was the age of wisdom, it was the age of foolishness,");
writer.println("it was the epoch of belief, it was the epoch of incredulity,");
writer.println("it was the season of Light, it was the season of Darkness,");
writer.println("it was the spring of hope, it was the winter of despair,");
writer.println("we had everything before us, we had nothing before us");
String string = stringWriter.toString();
Run Code Online (Sandbox Code Playgroud)

还有java.io.BufferedWriter一个newLine()方法没有提及的事实.


And*_*s_D 5

一个非常有效且独立于平台的解决方案是使用行分隔符的系统属性和 StringBuilder 类来构建字符串:

String separator = System.getProperty("line.separator");
String[] lines = {"Line 1", "Line 2" /*, ... */};

StringBuilder builder = new StringBuilder(lines[0]);
for (int i = 1; i < lines.length(); i++) {
    builder.append(separator).append(lines[i]);
}
String multiLine = builder.toString();
Run Code Online (Sandbox Code Playgroud)


小智 5

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

String out = Joiner.on(newline).join(ImmutableList.of(
    "line1",
    "line2",
    "line3"));
Run Code Online (Sandbox Code Playgroud)


jpf*_*ire 5

使用Properties.loadFromXML(InputStream)。不需要外部库。

比凌乱的代码更好(因为您需要关注可维护性和设计),因此最好不要使用长字符串。

首先阅读xml属性:

 InputStream fileIS = YourClass.class.getResourceAsStream("MultiLine.xml");
 Properties prop = new Properies();
 prop.loadFromXML(fileIS);
Run Code Online (Sandbox Code Playgroud)


那么您可以以更易于维护的方式使用多行字符串...

static final String UNIQUE_MEANINGFUL_KEY = "Super Duper UNIQUE Key";
prop.getProperty(UNIQUE_MEANINGFUL_KEY) // "\n    MEGA\n   LONG\n..."
Run Code Online (Sandbox Code Playgroud)


MultiLine.xml`位于相同的文件夹YourClass中:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">

<properties>
    <entry key="Super Duper UNIQUE Key">
       MEGA
       LONG
       MULTILINE
    </entry>
</properties>
Run Code Online (Sandbox Code Playgroud)

PS .:您可以将<![CDATA["... "]]>用于类似xml的字符串。


Nam*_*man 5

使用JDK/12 早期访问版本 #12,现在可以在 Java 中使用多行字符串,如下所示:

String multiLine = `First line
    Second line with indentation
Third line
and so on...`; // the formatting as desired
System.out.println(multiLine);
Run Code Online (Sandbox Code Playgroud)

这导致以下输出:

First line
    Second line with indentation
Third line
and so on...
Run Code Online (Sandbox Code Playgroud)

编辑:推迟到 java 13

  • 正如 cybersoft 在其他评论中所说,原始字符串文字 (JEP326) 已从最终的 JDK12 中删除,但已创建另一个 JEP 来添加“文本块”,可以在 JDK 13 中作为预览完成 (2认同)

Luk*_*zda 5

Java 13 预览版:

文本块来到 Java。Java 13 提供了 Mala Gupta 期待已久的多行字符串

通过文本块,Java 13 使您可以更轻松地处理多行字符串文字。您不再需要转义字符串文字中的特殊字符或对跨越多行的值使用连接运算符。

文本块使用三个双引号 (""") 作为开始和结束分隔符来定义。开始分隔符后面可以跟零个或多个空格和一个行终止符。

例子:

 String s1 = """
 text
 text
 text
 """;
Run Code Online (Sandbox Code Playgroud)


小智 5

看到了所有的答案,我认为没有人提到比在较新版本的 java 中你可以这样做:

String s = """
    This
    is 
    a
    multiline
    string
    """;
System.out.println(s);
Run Code Online (Sandbox Code Playgroud)

这是它打印的内容:

This
is
a
multiline
string
Run Code Online (Sandbox Code Playgroud)


Jos*_*ren 0

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