Вы можете попробовать использовать AppDomain.UnhandledException и посмотреть, позволяет ли это его поймать.
** EDIT *
Вот несколько более подробная информация , которая может быть полезна (долго читается).
Стивен Колеборн создал предложение для добавления многострочных строк в Java 7.
Кроме того, Groovy уже поддерживает многострочные строки .
Я предлагаю использовать утилиту, предложенную ThomasP, а затем связать ее с процессом сборки. Внешний файл все еще присутствует, чтобы содержать текст, но файл не читается во время выполнения. Тогда рабочий процесс выглядит следующим образом:
class TextBlock {...
, за которым следует статическая строка, которая автоматически генерируется из файла ресурсов Единственный известный мне способ - объединить несколько строк со знаком плюс.
Поздняя модель 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.
Это то, что вы не должны никогда использовать, не задумываясь о том, что он делает. Но для одноразовых сценариев я использовал это с большим успехом:
Пример:
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();
}
См. Java Stringfier . Превращает ваш текст в Java-блок StringBuilder, экранирующий при необходимости.
Альтернативой, которую я еще не видел в качестве ответа, является 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();
Также не упоминается тот факт, что java.io.BufferedWriter
имеет метод newLine()
.
Звучит так, как будто вы хотите создать многострочный литерал, которого нет в 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";
По сравнению с 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();
По сравнению с 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"
);
По сравнению с 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"
);
Если вы хотите новую строку для вашей конкретной системы, вам нужно либо использовать System.getProperty("line.separator")
, либо вы можете использовать %n
в String.format
.
Другой вариант - поместить ресурс в текстовый файл и просто прочитать содержимое этого файла. Это было бы предпочтительным для очень больших строк, чтобы избежать ненужного раздувания ваших файлов классов.
Другим вариантом может быть сохранение длинных строк во внешнем файле и считайте файл в строку.
Если вы определите свои строки в файле свойств, это будет выглядеть намного хуже. IIRC, это будет выглядеть так:
string:text\u000atext\u000atext\u000a
В целом разумно не встраивать большие строки в исходный код. Возможно, вы захотите загрузить их как ресурсы, возможно, в XML или в удобочитаемом текстовом формате. Текстовые файлы можно либо прочитать во время выполнения, либо скомпилировать в исходный код Java. Если вы в конечном итоге поместите их в исходный код, я предлагаю поместить +
впереди и опустить ненужные новые строки:
final String text = ""
+"text "
+"text "
+"text"
;
Если у вас есть новые строки, вам может потребоваться какой-либо метод объединения или форматирования:
final String text = join("\r\n"
,"text"
,"text"
,"text"
);
Плюсы преобразуются в StringBuilder.append, за исключением случаев, когда обе строки являются константами, поэтому компилятор может комбинировать их во время компиляции. По крайней мере, так оно и есть в компиляторе Sun, и я подозреваю, что большинство, если не все другие компиляторы будут делать то же самое.
Итак:
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";
То есть нет никакого наказания за разбиение строковых литералов на несколько строк со знаком плюс для удобства чтения.
К сожалению, в Java нет многострочных строковых литералов. Вам нужно либо объединить строковые литералы (с использованием + или StringBuilder, что является двумя наиболее распространенными подходами к этому), либо прочитать строку из отдельного файла.
Для больших многострочных строковых литералов я был бы склонен использовать отдельный файл и прочтите его с помощью getResourceAsStream ()
(метод класса Class
). Это упрощает поиск файла, поскольку вам не нужно беспокоиться о текущем каталоге, а не о том, где был установлен ваш код. Это также упрощает упаковку, потому что вы действительно можете сохранить файл в своем jar-файле.
Предположим, вы ' re в классе Foo. Просто сделайте что-нибудь вроде этого:
Reader r = new InputStreamReader(Foo.class.getResourceAsStream("filename"), "UTF-8");
String s = Utils.readAll(r);
Еще одна неприятность заключается в том, что в Java нет стандартного метода «прочитать весь текст из этого Reader в String». Однако написать довольно легко:
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();
}
Определить мою строку в файле свойств?
Многострочные строки не допускаются в файлах свойств. Вы можете использовать \ n в файлах свойств, но я не думаю, что это хорошее решение в вашем случае.
Достаточно эффективным и независимым от платформы решением было бы использование системного свойства для разделителей строк и класса 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();
Вы можете объединить свои добавления в отдельный метод, например:
public static String multilineString(String... lines){
StringBuilder sb = new StringBuilder();
for(String s : lines){
sb.append(s);
sb.append ('\n');
}
return sb.toString();
}
В любом случае предпочтите StringBuilder
положительной нотации.
String newline = System.getProperty ("line.separator");
string1 + newline + string2 + newline + string3
Но лучшей альтернативой является использование String.format
String multilineString = String.format("%s\n%s\n%s\n",line1,line2,line3);
When a long series of + are used, only one StringBuilder is created, unless the String is determined at compile time in which case no StringBuilder is used!
The only time StringBuilder is more efficient is when multiple statements are used to construct the 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);
Note: Only one StringBuilder is created.
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
To clarify my question further, I'm not concerned about performance at all. I'm concerned about maintainability and design issues.
Make it as clear and simple as you can.
Вы можете использовать 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-строку вроде этой:
sed '1s/^/String s = \"/;2,$s/^/\t+ "/;2,$s/$/"/' file > file.java
, чтобы вы могли легко вырезать и вставить ее в свой источник.
Предварительный просмотр Java 13:
Текстовые блоки Прибывают в Java. Java 13 поставляет долгожданную многострочную строку Mala Gupta
С текстовыми блоками, Java 13 помогает Вам работать с многострочными строковыми литералами. Вы больше не должны выходить из специальных символов в строковых литералах или операторах конкатенации использования для значений, которые охватывают несколько строк.
Текстовый блок определяется с помощью трех двойных кавычек (""") как открытие и заключительные разделители. Вводный разделитель может сопровождаться нулем или большим количеством пробелов и разделителем строки.
Пример:
String s1 = """
text
text
text
""";
Простой вариант - отредактировать свой java-код с помощью такого редактора, как SciTE ( http://www.scintilla.org/SciTEDownload.html ), который позволяет вам обернуть текст так, чтобы длинные строки легко просматривались и редактировались. Если вам нужны escape-символы, вы просто вставляете их. Отключив опцию переноса, вы можете проверить, действительно ли ваша строка по-прежнему представляет собой длинную однострочную строку. Но, конечно, компилятор тоже скажет вам, если это не так.
Поддерживают ли Eclipse или NetBeans перенос текста в редакторе, я не знаю, потому что у них так много вариантов. Но если нет, было бы неплохо добавить.
Я получил немного раздражен чтением, что многоугольный синтаксис действительно был запланирован для JDK7 (после того, как около десятилетий Java существование?). Funnily, даже нет функции azeall () для чтения полного содержимого файла (только от JDK7, HuHH), поэтому код ниже читает отдельные строки.
/* 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)