ใน Java มีวิธีเขียนสตริงลิเทอรัลโดยไม่ต้องเว้นเครื่องหมายคำพูดหรือไม่?


111

สมมติว่าคุณมีสตริงลิเทอรัลที่มีเครื่องหมายอัญประกาศอยู่ข้างใน คุณสามารถหลีกหนีพวกเขาทั้งหมดได้ แต่มันเป็นความเจ็บปวดและยากที่จะอ่าน

ในบางภาษาคุณสามารถทำได้:

foo = '"Hello, World"';

อย่างไรก็ตามใน Java ''ใช้สำหรับchars ดังนั้นคุณจึงไม่สามารถใช้Strings ด้วยวิธีนี้ได้ บางภาษามีไวยากรณ์เพื่อแก้ไขปัญหานี้ ตัวอย่างเช่นใน python คุณสามารถทำได้:

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

Java มีอะไรที่คล้ายกันหรือไม่?


ที่เกี่ยวข้อง: stackoverflow.com/questions/2678483/…
Michael Mrozek

คำตอบนี้แสดงวิธีการวางสตริงที่ใช้ Escape หลายบรรทัดใน Eclispe
Jeff Axelrod

2
อัปเดต 2018: ลิเทอรัลสตริงดิบสำหรับ Java อาจจะมา ดูคำตอบของฉันด้านล่าง
VonC

นำเข้าแจ็คสัน 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('`', '"');

ส่วนใหญ่ฉันจะทำอะไรแบบนั้นสำหรับฟิลด์คงที่ เนื่องจากเป็นแบบคงที่โค้ดแทนที่สตริงจึงถูกเรียกหนึ่งครั้งเมื่อเริ่มต้นคลาส ดังนั้นโทษประสิทธิภาพของรันไทม์จึงแทบไม่มีอยู่จริงและทำให้โค้ดนั้นอ่านง่ายขึ้นมาก


คุณไม่จำเป็นต้องใช้ replaceAll หรือไม่?
Landon Kuhn

10
@ landon9720 ไม่ใช่. replace แทนที่การเกิดขึ้นทั้งหมดของลำดับอักขระ / อักขระด้วยลำดับอักขระ / อักขระอื่น .replaceAll ใช้ regex
abelito

ด้วยความอยากรู้คุณรู้หรือไม่ว่าคอมไพเลอร์ java จะทำให้สิ่งนี้ง่ายขึ้นเมื่อคอมไพล์?
ug_

2
ไม่ฉันไม่คิดว่าคอมไพเลอร์จะทำให้เรื่องนี้ง่ายขึ้น แต่มันไม่สำคัญจริงๆ เป็นการโทรที่ไม่แพงมากและถ้าฉันทำสิ่งนี้สำหรับสตริงสุดท้ายแบบคงที่เท่านั้นค่าใช้จ่ายจะเกิดขึ้นเพียงครั้งเดียวเมื่อโหลดคลาส นั่นเป็นราคาที่ฉันมักจะยินดีจ่ายสำหรับรหัสที่ดูดีกว่า :)
benjismith

3
แล้ว "\" ใน myString ล่ะ?
Anderson

10

อัปเดตธันวาคม 2018 (12 เดือนหลังจากนั้น):

ตัวอักษรของสตริงดิบ (ซึ่งอยู่ในรายชื่อสีเหลืองอำพัน ) จะไม่ให้มันไป JDK 12.
เห็นวิพากษ์วิจารณ์ที่นี่


อาจมี Java เวอร์ชันในอนาคต (10 หรือมากกว่า)

ดูJEPS 8196004ตั้งแต่เดือนมกราคม 2018: ( "JEP" คือ "JDK Enhancement Program" )

ร่าง JEP: ตัวอักษรสตริงดิบ

เพิ่มลิเทอรัลชนิดใหม่ซึ่งเป็นลิเทอรัลสตริงดิบให้กับภาษาโปรแกรม Java
เช่นเดียวกับตัวอักษรสตริงแบบดั้งเดิมตัวอักษรสตริงดิบผลิตเชือก แต่ไม่ได้ตีความหนีสตริงและสามารถขยายหลายบรรทัดของรหัสที่มา

แทนที่จะเป็น:

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 ต่อไป



4

คุณยังสามารถใช้StringEscapeUtilsจาก apache commons

UPDATE : หากมีใครสนใจตัวอย่างบางส่วนนี่คือลิงค์ที่มีประโยชน์: https://dzone.com/articles/commons-lang-3-improved-and-powerful-StringEscapeUtils


2
คุณช่วยเพิ่มตัวอย่างที่อาจเป็นไปได้จากคำถามที่อธิบายวิธีการแก้ปัญหานี้
Bengt

3
ถือว่าไม่เหมาะสมในการอ้างอิงเฉพาะทรัพยากรอื่นที่อาจตอบคำถามได้ โปรดพิจารณาสรุปหน้าที่เชื่อมโยงกับตัวอย่างที่ตรงกับคำถาม
Bengt

ฉันดูและไม่คิดว่าจะตอบคำถามจริงๆ อินพุตของวิธีการแบบคงที่คือStrings ดังนั้นจึงไม่มีวิธีใดที่จะมีค่าที่จัดรูปแบบไว้อย่างดีในโค้ดของคุณ สันนิษฐานว่าคุณสามารถใช้วิธีการเหล่านี้เพื่ออ่านจากไฟล์เป็น a Stringได้ แต่ฉันไม่คิดว่านั่นเป็นคำถามที่นี่
Tom Harrison

คลาสที่เชื่อมโยง (org.apache.commons.lang3.StringEscapeUtils) เลิกใช้แล้วและแทนที่ด้วยorg.apache.commons.text.StringEscapeUtils
jcarter

-4

สิ่งต่อไปนี้ดูเหมือนจะใช้ได้กับฉัน:

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

ฉันคิดว่าเนื่องจาก char เป็นประเภทตัวแปรดั้งเดิมสำหรับ String จึงสามารถรวม Strings และ chars ได้ (อย่างน้อยคอมไพเลอร์ eclipse ก็ดูเหมือนจะไม่บ่น)


1
ฉันคิดว่าเนื่องจาก char เป็นประเภทตัวแปรดั้งเดิมสำหรับ String <- สมมติฐานของคุณไม่ถูกต้อง สำหรับเรื่องนั้นมันจะทำงานกับประเภทอื่นเช่น int เช่น: String x = "Some text" + 33 + "More text";
Najeeb

-6

หากคุณต้องการหลีกเลี่ยง'หรือ"ในสตริงของคุณคุณสามารถใช้รหัสต่อไปนี้:

String text = ...

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

คำถามถามเกี่ยวกับตัวอักษรสตริงในซอร์สโค้ด ขออภัยลองอีกครั้ง
michaelb958 - GoFundMonica
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.