Чи існує в Java спосіб, як написати рядковий літерал, не виходячи з лапок?


111

Скажімо, у вас є лінійка String з великою кількістю лапок. Ви могли б уникнути їх усіх, але це біль і важко читати.

У деяких мовах ви можете просто зробити це:

foo = '"Hello, World"';

У Java, однак, ''використовується для chars, тому ви не можете використовувати його для Strings таким чином. Деякі мови мають синтаксис, щоб обійти це. Наприклад, у python ви можете це зробити:

"""A pretty "convenient" string"""

Чи є у Java щось подібне?



Ця відповідь показує, як вставити багаторядкові рядки, що увійшли в Eclispe.
Джефф Аксельрод

2
Оновлення 2018 року: можливі вихідні літеральні рядки для Java. Дивіться мою відповідь нижче
VonC

імпорт jackson ObjectMapper тоді System.out.println(mapperObj.writeValueAsString(mapperObj.readValue(str, Object.class)));
Kervvv

оновлення Q4 2018: необмежений буквальний рядок ще не надходить. Дивіться мою оновлену відповідь .
VonC

Відповіді:


74

Відповідь - ні, і доказ міститься в специфікації мови Java :

  StringLiteral:
   "StringCharacters"

  StringCharacters:
   StringCharacter
   | StringCharacters StringCharacter

  StringCharacter:
   InputCharacter but not " or \
   | EscapeSequence

Як ви бачите, а StringLiteralможе бути просто пов'язаний "і не може містити спеціального символу без втеч ..

Побічна примітка: ви можете вбудувати Groovy у свій проект, це розширить синтаксис Java, що дозволяє вам використовувати '''multi line string ''', ' "string with single quotes" 'а також "string with ${variable}".


141

Ні, і мене завжди дратувало відсутність різних синтаксисів рядково-буквальних синтаксисів на Java.

Ось хитрість, яку я час від часу використовував:

String myString = "using `backticks` instead of quotes".replace('`', '"');

Я в основному роблю щось подібне для статичного поля. Оскільки він статичний, код заміни рядка викликається один раз, при ініціалізації класу. Таким чином, покарання за виконання часу практично не існує, і це робить код значно більш розбірливим.


вам не потрібно використовувати substituAll?
Ландон Кун

10
@ landon9720 Ні, .replace замінює всі випадки послідовності символів / символів іншою послідовністю символів / символів. .replaceВсі використовують регулярний вираз.
abelito

З цікавості ви знаєте, чи компілятор Java спростив би це при складанні?
ug_

2
Ні, я не думаю, що компілятор спростив би це. Але це насправді не має значення. Це дуже недорогий дзвінок, і якщо я це роблю лише для статичних кінцевих рядків, вартість виникне лише один раз, після завантаження класу. Це ціна, яку я зазвичай готовий платити за приємніший вигляд коду :)
benjismith,

3
Тоді як щодо "\" у myString?
Андерсон

10

Оновлення грудня 2018 року (через 12 місяців):

Сирі літеральні рядки (які є у списку бурштину ) не перейдуть до JDK 12.
Дивіться критику тут .


Можливо, у майбутній версії Java (10 або більше).

Дивіться JEPS 8196004 від січня 2018 року: ( "JEP" - це "програма розширення JDK" )

Проект JEP: Сирі строкові літерали

Додайте новий вид літералу, необроблений рядковий літерал, до мови програмування Java.
Як і традиційний літеральний рядок, необроблений літеральний рядок створює String, але не інтерпретує уникнення рядків і може охоплювати кілька рядків вихідного коду .

Тож замість:

Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar");
String html = "<html>\n"
              "    <body>\n" +
              "         <p>Hello World.</p>\n" +
              "    </body>\n" +
              "</html>\n";
System.out.println("this".matches("\\w\\w\\w\\w"));

Ви зможете ввести:

Runtime.getRuntime().exec(`"C:\Program Files\foo" bar"`);
    
String html = `<html>
                   <body>
                       <p>Hello World.</p>
                   </body>
               </html>
              `;

System.out.println("this".matches(`\w\w\w\w`));

Акуратно!

Але це все ще лише проект : його потрібно буде опублікувати, подати, стати кандидатом і профінансувати, перш ніж буде завершено і перейти в наступний JDK.


5

Проста відповідь: Ні.

Для довших рядків, які потрібно вийти, я зазвичай читаю їх із якогось зовнішнього ресурсу.


4

ви також можете використовувати StringEscapeUtils з apache commons

ОНОВЛЕННЯ : Якщо когось цікавлять приклади, ось корисне посилання: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils


2
Чи можете ви, будь ласка, додати приклад, можливо, спираючись на питання, що ілюструє, як вирішити цю проблему?
Бенгт

3
Вважається неоптимальним лише посилання на інший ресурс, який може відповісти на питання. Будь ласка, розгляньте підсумовування пов’язаної сторінки із прикладом відповідності питанню.
Бенгт

Я подивився і не думаю, що насправді відповідає на питання. Входи до статичних методів є Strings, тому жодним чином не мати гарного форматованого значення у вашому коді. Імовірно, ви могли використовувати ці методи для читання з файлу в файл String, але я не думаю, що це питання тут.
Том Гаррісон

Пов'язаний клас (org.apache.commons.lang3.StringEscapeUtils) застарів і замінений org.apache.commons.text.StringEscapeUtils
jcarter

-4

Здається, що для мене працює таке:

String x = "Some Text" + '"' + "More Text" + '"' + "Even More Text";

Я думаю, тому що char - це примітивний тип змінної для String, Strings та символів, які можна комбінувати (принаймні компілятор eclipse, схоже, не скаржиться).


1
Я думаю, тому що char - це примітивний тип змінної для String <- Ваше припущення неправильне. З цього питання він також буде працювати з іншим типом, як int, як-от так: String x = "Some text" + 33 + "More text";
Najeeb

-6

Якщо ви хочете бігти 'або "в рядку, ви можете використовувати наступний код:

String text = ...

text = text.replaceAll("('|\")", "\\\\$1");

Питання про рядкові літерали у вихідному коді. Вибачте, спробуйте ще раз.
michaelb958 - GoFundMonica
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.