ทำไมไม่มี String.Empty ใน Java?


260

ฉันเข้าใจว่าทุกครั้งที่ฉันพิมพ์สตริงตัวอักษร""วัตถุสตริงเดียวกันมีการอ้างอิงในสระว่ายน้ำสตริง

แต่ทำไมไม่สตริง API ได้แก่public static final String Empty = "";ดังนั้นฉันสามารถใช้การอ้างอิงไปยังString.Empty?

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

ดังนั้นมีเหตุผลการออกแบบที่ยิ่งใหญ่ที่อยู่เบื้องหลังไม่มีสตริงหรือผู้สร้างภาษาก็ไม่แชร์มุมมองของฉัน?


5
Aidanc: ฉันคิดว่าเขาหมายถึงสถานการณ์ที่คุณทำสิ่งที่ชอบoutputBlah = ""และเขาอาจชอบsomething == String.Emptyมากกว่าsomething.Length > 0เช่นกัน (คุณข้ามการตรวจสอบเป็นโมฆะ)
Skurmedel

2
@Aidanc - เขากำลังมองหา "สมาชิกที่ว่างเปล่า" เช่นCollections.EMPTY_SETไม่ใช่ฟังก์ชันเพื่อตรวจสอบสตริง "emptiness"
Tim Stone

2
@Aidanc: สิ่งนี้เป็นแรงบันดาลใจจริง ๆ แล้ว 'TextBox.setText ("");'
Tom Tresansky

3
มีความเป็นString.isEmpty()ฟังก์ชั่น ... ทำไมคุณต้องการString.EMPTY?
Buhake Sindi

8
String.isEmpty()ไม่ส่งคืนสตริงว่าง
Steve Kuo

คำตอบ:


191

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

โดยเฉพาะอย่างยิ่งการพิจารณาว่าStrings ไม่เปลี่ยนรูปไม่เหมือนกับที่คุณได้รับสตริงว่างก่อนและดำเนินการบางอย่างกับมัน - ดีที่สุดที่จะใช้StringBuilder(หรือStringBufferถ้าคุณต้องการที่จะปลอดภัยเธรด) และเปลี่ยนเป็นสตริง

อัปเดต
จากความคิดเห็นของคุณเป็นคำถาม:

สิ่งนี้เป็นแรงบันดาลใจ TextBox.setText("");

ฉันเชื่อว่ามันจะถูกต้องตามกฎหมายทั้งหมดในการจัดชั้นเรียนที่เหมาะสมของคุณ:

private static final String EMPTY_STRING = "";

จากนั้นอ้างอิงตามรหัสของคุณ

TextBox.setText(EMPTY_STRING);

อย่างน้อยที่สุดคุณก็ชัดเจนว่าคุณต้องการสตริงว่างเปล่าแทนที่จะลืมกรอก String ใน IDE ของคุณหรือบางอย่างที่คล้ายกัน


14
ฉันจะยัง +1 คุณอยู่ แต่ฉันรู้สึกสกปรกเพราะคุณพูดถึงStringBuilderโดยที่ไม่ได้พูดถึงว่าเก้าครั้งจากสิบครั้งนั้นไม่เหมาะสมเลยที่จะใช้StringBuilderแทนที่จะเชื่อมโยงกัน
Randolpho

85
ฉันมักจะชอบ string.empty ส่วนใหญ่เป็นเพราะมันชัดเจนมากขึ้น นอกจากนี้ยังมีสถานการณ์อัตราที่ยากที่จะแยกความแตกต่างทางสายตาและสิ่งต่าง ๆ เช่น "" " ในท้ายที่สุดขณะที่คนอื่นสังเกตว่ามันเป็นเพียงหนึ่งในสิ่งที่ไม่มีความหมายสไตล์ที่ให้อาหารสัตว์เราเถียงมากกว่าเมื่อเราเบื่อกับการทำงานจริง =)
JohnFx

@Nodel M: เกี่ยวกับเวลาในการคอมไพล์ฉันจะสมมติว่าถ้ามีตัวอักษรสตริง 2 ตัวที่กำหนดไว้ในไฟล์ต้นฉบับ 2 ไฟล์ที่มีค่าสตริงเหมือนกันเมื่อคอมไพเลอร์มาถึงอันดับที่ 2 จำเป็นต้องทำการตรวจสอบบางอย่างเพื่อหา " เฮ้ฉันรู้แล้วเกี่ยวกับสายนี้จากที่นี่ " ฉันยอมรับว่าไม่มีผู้เชี่ยวชาญในคอมไพเลอร์ java แต่จะเป็นเช่นไรได้อย่างไร และฉันคิดว่าการข้ามการตรวจสอบนั้นจะส่งผลให้เวลาในการรวบรวมสั้นลง
Tom Tresansky

@Tom - ฉันเชื่อว่า String Interning เสร็จแล้วที่รันไทม์ไม่ใช่เวลารวบรวมดังนั้นจริง ๆ แล้วถ้าคุณมีสตริงว่างเป็นค่าคงที่ในไฟล์อื่นคอมไพเลอร์จำเป็นต้องอ้างอิงคลาสนั้นเพื่อแก้ไขตัวอักษร String
Noel M

1
@ Randolpho เมื่อใช้การต่อสายสตริงของคุณเป็นจริงโดยใช้ StringBuilder ภายใต้ประทุน
whiskeysierra

133

ใช้ org.apache.commons.lang.StringUtils.EMPTY


30
ดูดีกว่าและอ่านง่ายกว่า "" ที่ว่างเปล่า ฉันหวังว่ามันจะไม่ใช่แค่ฉัน
Lakatos Gyula

2
@LakatosGyula - ฉันคิดว่ามันอาจจะเป็น (แค่คุณ) โปรแกรมเมอร์ Java ที่เชี่ยวชาญไม่มีปัญหาในการอ่าน""... และส่วนใหญ่อาจคัดค้านเกี่ยวกับการใช้เสียงEMPTYยกเว้นในสถานการณ์เฉพาะที่EMPTYมีความหมายเฉพาะโดเมน (และในกรณีเช่นนี้อาจมีชื่อที่เหมาะสมกว่า)
สตีเฟ่นซี

14
@LakatosGyula มันไม่ใช่แค่คุณ ฉันเปลี่ยนจาก Java ไปเป็น. NET และ String.Empty เป็นคุณสมบัติที่ฉันยินดีที่ได้พบในกรอบ ฉันชอบธรรมชาติที่ชัดเจนของมันมากกว่าชุดคำพูดที่ว่างเปล่า
yohohohoho

64
@StephenC เมื่อฉันเห็นสิ่งที่ว่างเปล่า "" สิ่งแรกที่กระโดดในใจของฉันว่ามันเป็นข้อผิดพลาดใครบางคนยังไม่เสร็จฟังก์ชั่นอื่น ๆ ด้วย String.EMPTY ฉันรู้ว่าผู้พัฒนาตั้งใจจะคืนสตริงว่างเปล่า
Lakatos Gyula

1
ยังมีประโยชน์สำหรับทุกครั้งที่ผู้ให้เช่าพูดว่า "ใช้ค่าคงที่ที่มีชื่อแทน blah blah blah" โปรแกรมเมอร์ทุกคนรู้ว่า "" ไม่ใช่เวทมนตร์ แต่การไม่อธิบายให้ลูกค้าฟังจะดีกว่า
LizH

28

หากคุณต้องการเปรียบเทียบกับสตริงว่างโดยไม่ต้องกังวลเกี่ยวกับค่า Null คุณสามารถทำสิ่งต่อไปนี้

if ("".equals(text))

ท้ายที่สุดคุณควรทำในสิ่งที่คุณเชื่อว่าชัดเจนที่สุด โปรแกรมเมอร์ส่วนใหญ่ถือว่า "" หมายถึงสตริงที่ว่างเปล่าไม่ใช่สตริงที่บางคนลืมที่จะใส่อะไรลงไป

หากคุณคิดว่ามีข้อได้เปรียบด้านประสิทธิภาพคุณควรทดสอบ หากคุณไม่คิดว่าการทดสอบนั้นมีค่าสำหรับตัวคุณเองมันเป็นเครื่องบ่งชี้ที่ดีว่ามันไม่คุ้มค่า

ดูเหมือนว่าคุณจะพยายามแก้ปัญหาที่ได้รับการแก้ไขเมื่อภาษานั้นถูกออกแบบมานานกว่า 15 ปีแล้ว


1
ฉันค่อนข้างจะช้าไปงานปาร์ตี้ แต่เนื่องจากสตริง Java ไม่เปลี่ยนรูปฉันเชื่อว่าสตริงว่างทั้งหมดใน JVM เป็นเพียงการอ้างอิงที่แตกต่างกันไปยังวัตถุ String เดียวกัน ดังนั้นเพียงแก้ไขข้อผิดพลาดดังต่อไปนี้: if ("" == text)
Ajoy Bhatia

12
@ JoyBhatia ปัญหาคือคุณสามารถสร้างสตริงว่างใหม่ได้ if ("" == new String())เป็นเท็จ การทดสอบที่ดีกว่าif(text.isEmpty())
Peter Lawrey

1
@ JoyBhatia - เฉพาะในกรณีที่มีการฝึกงานสตริง stackoverflow.com/questions/10578984/what-is-string-interning
Davor

9

ถ้าคุณต้องการให้ค่าคงที่ String.EMPTY คุณสามารถสร้างคลาสสุดท้ายแบบคงที่ยูทิลิตี้ชื่อ "Constants" (ตัวอย่าง) ในโครงการของคุณ คลาสนี้จะรักษาค่าคงที่ของคุณรวมถึงสตริงว่าง ...

ในความคิดเดียวกันคุณสามารถสร้าง ZERO หนึ่งค่าคงที่ int ... ที่ไม่มีอยู่ในคลาส Integer แต่อย่างที่ฉันแสดงความคิดเห็นมันเป็นความเจ็บปวดในการเขียนและอ่าน:

for(int i=Constants.ZERO; ...) {
    if(myArray.length > Constants.ONE) {
        System.out.println("More than one element");
    }
}

เป็นต้น


8

Apache StringUtils แก้ไขปัญหานี้ด้วย

ความล้มเหลวของตัวเลือกอื่น ๆ :

  • isEmpty () - ไม่ปลอดภัย ถ้าสตริงเป็นโมฆะโยน NPE
  • length () == 0 - อีกครั้งไม่ปลอดภัย ยังไม่คำนึงถึงสตริง whitespace ด้วย
  • เปรียบเทียบกับค่าคงที่ว่างเปล่า - อาจไม่ปลอดภัย ปัญหาช่องว่าง

ได้รับ StringUtils เป็นอีกหนึ่งห้องสมุดที่ใช้ลากไปรอบ ๆ แต่มันทำงานได้ดีมากและประหยัดเวลาและไม่ต้องยุ่งยากในการตรวจสอบค่า Null หรือจัดการ NPE ได้อย่างสง่างาม


3
ดังนั้น ... ดูเหมือนว่าเพียงตัวเลือกที่ปลอดภัยเป็นที่น่ากลัวสภาพ Yoda: "".equals(s)?
โกหกไรอัน

8

อย่าเพิ่งพูดว่า "พูลหน่วยความจำของสตริงนั้นถูกนำมาใช้ใหม่ในรูปแบบตัวอักษรกรณีปิด" สิ่งที่คอมไพเลอร์ทำภายใต้ประทุนไม่ใช่จุดที่นี่ คำถามนี้สมเหตุสมผลโดยเฉพาะจำนวนคะแนนที่ได้รับ

มันเกี่ยวกับความสมมาตรหากไม่มี APIs ก็ยากที่จะใช้กับมนุษย์ Java SDK ก่อนหน้านั้นไม่สนใจกฎและตอนนี้มันก็สายเกินไป นี่คือตัวอย่างเล็ก ๆ น้อย ๆ ที่อยู่บนหัวของฉันอย่าลังเลที่จะชิปในตัวอย่าง "รายการโปรด" ของคุณ:

  • BigDecimal.ZERO แต่ไม่มี AbstractCollection.EMPTY, String.EMPTY
  • Array.length แต่ List.size ()
  • List.add (), Set.add () แต่ Map.put (), ByteBuffer.put () และอย่าลืม StringBuilder.append (), Stack.push ()

แม้ว่าคุณจะตั้งชื่อความยาวของพารามิเตอร์รายการ () คุณยังคงต้องการวงเล็บเนื่องจากเป็นวิธีการ Array.length เป็นตัวแปรสุดท้ายสาธารณะซึ่งใช้ได้เฉพาะเนื่องจากอาร์เรย์ไม่เปลี่ยนรูป ดังนั้นคุณยังคงมี Array.length และ List.length () ฉันจะยืนยันว่ามีความสับสนและมีแนวโน้มที่จะเกิดข้อผิดพลาด สำหรับ. append () และ. push () ในขณะที่พวกเขาทำงานที่คล้ายกันฉันคิดว่าพวกเขามีชื่อเหมาะสม การต่อท้ายสตริงเป็นสิ่งที่คุณกำลังทำอยู่ แต่คุณไม่ต้อง "ผนวก" สแต็กคุณจะกดและป๊อปอัพค่า และ StringBuilder.push () จะแปลว่า StringBuilder.pop () ซึ่งไม่สามารถทำได้
Craig Parton

อินเทอร์เฟซที่สอดคล้องช่วยด้วยอัลกอริทึมเช่นกัน หากอัลกอริทึมต้องการความยาวของคอลเลกชันความยาว (T) หรือ T.length () คือทั้งหมดที่เราใส่ใจ ในทำนองเดียวกันการเพิ่มในตอนท้ายของสแต็ครายการหรือสตริงสามารถทำได้โดยการเพิ่ม universal () หรือผนวก () คุณพูดถึงว่าอาเรย์ใน Java เป็นชนิดที่ไม่เปลี่ยนรูป / builtin พร้อมกับความยาว ไม่เป็นไรแปลว่าไม่สามารถจัดการหรือสร้างรหัสสำหรับความยาว (T) หรือ T.length () Kotlin สร้างวิธีการที่แท้จริงสำหรับกรณีต่างๆ
Slawomir

แต่เมธอด length () ที่มีความสม่ำเสมอนั้นให้เราตรวจสอบความยาวได้เท่านั้น มีประโยชน์อย่างไร? หากเป้าหมายของคุณคือรายการและอาร์เรย์แบบนามธรรมเพื่อให้สามารถใช้งานได้บางวิธีผ่านอินเทอร์เฟซคุณต้องมีวิธีการอ่านหรือเขียนข้อมูลที่สอดคล้องกัน ดังนั้นตอนนี้คุณต้องสร้างเมธอด get (), set () และ add () โดยพื้นฐานแล้วคุณกำลังสร้างมุมมองรายการที่ทำงานได้น้อยลงของอาเรย์ เนื่องจาก Arrays.asList () พร้อมใช้งานใช้งานง่ายและมีน้ำหนักเบาทำไมต้องคิดค้นล้อใหม่ อาร์เรย์รายการ StringBuilders และกองทั้งหมดมีวัตถุประสงค์เฉพาะ ดูเหมือนจะดีกว่าในการออกแบบส่วนต่อประสานของคุณเพื่อให้ใช้งานได้พอดี
Craig Parton

5

""ตัวอักษรทั้งหมดนั้นเป็นวัตถุเดียวกัน ทำไมจึงต้องเพิ่มความซับซ้อนเป็นพิเศษ พิมพ์ได้นานขึ้นและชัดเจนน้อยลง (ค่าใช้จ่ายในการคอมไพเลอร์น้อยที่สุด) เนื่องจากสตริงของ Java เป็นวัตถุที่ไม่เปลี่ยนรูปแบบจึงไม่จำเป็นต้องแยกแยะความแตกต่างระหว่างพวกเขายกเว้นอาจเป็นสิ่งที่มีประสิทธิภาพ แต่ด้วยสตริงตัวอักษรที่ว่างเปล่าที่ไม่ใช่เรื่องใหญ่

หากคุณต้องการEmptyStringค่าคงที่จริงๆทำด้วยตัวเอง แต่สิ่งที่มันจะทำคือสนับสนุนให้โค้ด verbose มากยิ่งขึ้น จะไม่มีประโยชน์ใด ๆ ในการทำเช่นนั้น


27
x = String.Emptyx = ""บ่งบอกถึงความตั้งใจที่ดีกว่า หลังอาจเป็นการละเว้นโดยไม่ตั้งใจ การบอกว่าไม่มีประโยชน์ใด ๆ ที่ไม่ถูกต้อง
Jeffrey L Whitledge

@ Jeffrey: ฉันไม่คิดว่าฉันเห็นด้วยอย่างยิ่ง มันเป็นหนึ่งในสิ่งเหล่านี้ที่ฉันคิดว่าไม่มีกฎที่ยากและรวดเร็ว
Donal Fellows

ใช่สิ่งสำคัญคือต้องชี้ให้เห็นว่าคอมไพเลอร์ java ตรวจสอบว่ามีตัวอักษรสตริงอยู่แล้วก่อนที่จะสร้างอินสแตนซ์ใหม่ในพูลสตริง
rds

1
@ Jeffrey - รู้ว่านี่คือการสนทนาที่เก่าแก่และเป็นอัตนัย x = String.Emptyบ่งบอกถึงเจตนาที่แท้จริง แต่สมมติว่าภาษานั้นมีค่าคงที่String.Emptyเมื่อคุณพบx = ""ว่าคุณยังรู้มากเกี่ยวกับเจตนาราวกับว่าไม่มีค่าคงที่ คุณจะต้องรับประกันว่าสถานที่ทั้งหมดในรหัสโลกของ Java ที่สตริงว่างเปล่าเป็นแบบไม่ใช้""เพื่อรับข้อมูลที่คุณพูดถึง กระแทกแดกดัน C # ใช้ค่าคงที่และกระตุ้นให้ใช้ดังนั้นฉันกล่าวว่าฉันรู้ว่ามันเป็นการสนทนาที่มีความมั่นใจมาก
chiccodoro

@chiccodoro - ใช่มันเป็นเรื่องจริง นั่นเป็นสาเหตุที่สตริงตัวอักษรว่างเปล่า""ควรผิดกฎหมายเพื่อแยกแยะอุบัติเหตุ ฉันล้อเล่น!
Jeffrey L Whitledge

4

หากต้องการเพิ่มสิ่งที่ Noel M ระบุไว้คุณสามารถดูคำถามนี้และคำตอบนี้แสดงให้เห็นว่าค่าคงที่นั้นถูกนำมาใช้ซ้ำ

http://forums.java.net/jive/message.jspa?messageID=17122

ค่าคงที่สตริงมักจะ "ฝึกงาน" ดังนั้นจึงไม่จำเป็นต้องมีค่าคงที่ดังกล่าว

String s=""; String t=""; boolean b=s==t; // true

1
ลิงก์ตาย
Dieter

3

ฉันเข้าใจว่าทุกครั้งที่ฉันพิมพ์สตริงตัวอักษร "" วัตถุสตริงเดียวกันจะถูกอ้างอิงในกลุ่มสตริ
ไม่มีการรับประกันดังกล่าว และคุณไม่สามารถเชื่อถือได้ในแอปพลิเคชันของคุณมันขึ้นอยู่กับ jvm ในการตัดสินใจ

หรือผู้สร้างภาษาไม่ได้แบ่งปันมุมมองของฉันหรือไม่
อ๋อ สำหรับฉันดูเหมือนสิ่งที่มีลำดับความสำคัญต่ำมาก


6
ไม่มีการรับประกันดังกล่าวเกิดขึ้น ... อืม JLS จะระบุว่าเป็นอย่างนั้น
Tim Stone

@Tim ไม่ใช่ว่าคุณจะโทร 'ฝึกงาน' มันง่ายที่จะสร้างสองสายใหญ่เท่ากันโดยทางโปรแกรมและตรวจสอบ
Nikita Rybak

@Tim ตัวอย่างเช่นทำซ้ำ+ = "a"; 100 ครั้งทำเช่นเดียวกันกับbและตรวจสอบ
Nikita Rybak

5
คุณพูดถูก แต่สิ่งที่คุณอธิบายไม่ใช่ตัวอักษรสตริงหรือนิพจน์ที่สามารถรับประกันผลลัพธ์ได้ในเวลารวบรวม (เช่นString username = "Bob" + " " + "Smith";) สตริงที่สร้างโดยทางโปรแกรมไม่มีการรับประกันว่าจะถูกฝึกงานเว้นแต่คุณจะโทรintern()ตามที่คุณระบุไว้อย่างชัดเจน สถานการณ์ของ OP อธิบายถึงการใช้สตริงตัวอักษรว่าง""ตลอดทั้งรหัสซึ่งเป็นกรณีที่จะเกิดขึ้นโดยอัตโนมัติ
Tim Stone

@Tim String a = ""; for(int i = 0; i < 100; i++) {a += "a";} String b = ""; for(int i = 0; i < 100; i++) {b += "b";} a.intern(); b.intern();ตอนนี้aและbชี้ไปที่ตำแหน่งหน่วยความจำเดียวกันใน PermGen ดูบทความนี้
1ac0

1

ตอบกลับล่าช้า แต่ฉันคิดว่ามันเพิ่มสิ่งใหม่ในหัวข้อนี้

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

ค่าคงที่จะมีประโยชน์เพราะจะป้องกันข้อผิดพลาดบางอย่างของรหัสจากการไม่สังเกตเห็น

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

OTOH ค่าคงที่ไลบรารีชื่อ EMPTY หากมีข้อผิดพลาดเดียวกันจะสร้างข้อผิดพลาดคอมไพเลอร์สำหรับบางสิ่งเช่น EM PTY

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

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

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


-16

สำหรับผู้ที่อ้างสิทธิ์""และString.Emptyใช้แทนกันได้หรือ""ดีกว่าคุณผิดมาก

ทุกครั้งที่คุณทำบางสิ่งเช่น myVariable = ""; คุณกำลังสร้างตัวอย่างของวัตถุ ถ้าวัตถุ String ของ Java มีค่าคงที่ว่างเปล่าของสาธารณะจะมีเพียง 1 ตัวอย่างของวัตถุ ""

เช่น: -

String.EMPTY = ""; //Simply demonstrating. I realize this is invalid syntax

myVar0 = String.EMPTY;
myVar1 = String.EMPTY;
myVar2 = String.EMPTY;
myVar3 = String.EMPTY;
myVar4 = String.EMPTY;
myVar5 = String.EMPTY;
myVar6 = String.EMPTY;
myVar7 = String.EMPTY;
myVar8 = String.EMPTY;
myVar9 = String.EMPTY;

10 (11 รวมถึง String.EMPTY) ตัวชี้ไปยัง 1 วัตถุ

หรือ: -

myVar0 = "";
myVar1 = "";
myVar2 = "";
myVar3 = "";
myVar4 = "";
myVar5 = "";
myVar6 = "";
myVar7 = "";
myVar8 = "";
myVar9 = "";

10 ตัวชี้ถึง 10 วัตถุ

สิ่งนี้ไม่มีประสิทธิภาพและทั่วทั้งแอพพลิเคชันขนาดใหญ่

บางทีคอมไพเลอร์ Java หรือรันไทม์นั้นมีประสิทธิภาพเพียงพอที่จะชี้อินสแตนซ์ทั้งหมดของ "" ไปที่อินสแตนซ์เดียวกันโดยอัตโนมัติ แต่อาจไม่และทำการประมวลผลเพิ่มเติมเพื่อกำหนด


9
ผิดพลาดตามstackoverflow.com/questions/1881922/…สตริง "" จะถูกนำกลับมาใช้ใหม่จากกลุ่มสตริง
RealHowTo

1
ฉันระบุว่ามันอาจนำวัตถุเดียวกันกลับมาใช้ใหม่และถ้าเป็นเช่นนั้นก็ยังมีประสิทธิภาพน้อยลงเพราะต้องการค้นหาวัตถุนั้น (ในสตริงพูล) ดังนั้นฉันจะผิดอย่างไร โดยไม่คำนึงถึงมีสาเหตุหลายประการที่ทำให้ String.Empty ดีกว่ารวมถึงการป้องกันข้อผิดพลาดเช่น myVar = ""; ความสามารถในการอ่านและการปรับปรุงประสิทธิภาพที่ฉันได้กล่าวไปแล้ว เป็นวิธีปฏิบัติที่ดีที่จะใช้ค่าคงที่แทนการสร้างตัวอักษรสตริงหากไม่มีเหตุผลอื่น ง่ายต่อการบำรุงรักษาโค้ด
Antony Booth

1
ฉันสงสัยว่าข้อโต้แย้งด้านประสิทธิภาพของคุณนั้นถูกต้องเพราะ JLS บอกว่าค่าคงที่จะถือว่าเป็นตัวอักษรในเวลารวบรวม ( docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10 5 ) การอ่านเป็นอาร์กิวเมนต์ที่ดีกว่า
RealHowTo

3
@AntonySmith - ฉันคิดว่าคุณต้องเรียนรู้ภาษาจาวาเพิ่มขึ้นอีกเล็กน้อยหรือบางทีคุณอาจรู้ข้อผิดพลาดของคุณในตอนนี้ สตริง Java ไม่เปลี่ยนรูปและอยู่ในกลุ่ม ดังนั้นจึงมีเพียงหนึ่งวัตถุสตริงสำหรับ "" ใน JVM ไม่ว่าจะพบกี่ครั้งในรหัส คุณสามารถตรวจสอบว่าสตริงว่างเปล่าหรือไม่โดยทำif (text == "")
Ajoy Bhatia

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