2012-12-10 18 views
13

संभव डुप्लिकेट:
What is the purpose of the expression “new String(…)” in Java?स्ट्रिंग क्लास की प्रतिलिपि बनाने वाले निर्माता क्यों हैं?

अपरिवर्तनीय वर्गों वस्तुओं तो प्रतियां मूल के बराबर होगा तो क्यों जावा में String वर्ग एक प्रति निर्माता है? क्या यह एक गलती है या इस कार्यान्वयन के पीछे एक कारण है? जावा डॉक्स में यह निर्दिष्ट किया जाता है कि:

/** 
* Initializes a newly created {@code String} object so that it represents 
* the same sequence of characters as the argument; in other words, the 
* newly created string is a copy of the argument string. Unless an 
* explicit copy of {@code original} is needed, use of this constructor is 
* unnecessary since Strings are immutable. 
* 
* @param original 
*   A {@code String} 
*/ 
public String(String original) { 
.... 
....} 
+6

यह "बहुत स्थानीयकृत" नहीं है, यह एक बहुत ही उपयोगी और सूचनात्मक उत्तर के साथ बाद में ढूंढने वालों पर लागू एक अच्छा सवाल है। –

+3

देखें [यह] (http://stackoverflow.com/a/465682/1037210) उत्तर। – Lion

+0

ध्यान दें कि उल्लिखित समान प्रश्न के उत्तर अब आंशिक रूप से अप्रचलित माना जा सकता है। –

उत्तर

10

मुख्य कारण कॉपी करने के लिए एक स्ट्रिंग है "सामान ट्रिम", कि केवल क्या आवश्यक है करने के लिए अंतर्निहित चार सरणी ट्रिम करने के लिए है।

अंतर्निहित चार सरणी मुख्य रूप से बहुत बड़ी हो सकती है क्योंकि जब आप substring पर कॉल करके स्ट्रिंग बनाते हैं, तो चार सरणी को नए स्ट्रिंग इंस्टेंस और स्रोत स्ट्रिंग इंस्टेंस के बीच साझा किया जा सकता है; पहले चरित्र को ऑफ़सेट पॉइंट और लंबाई शामिल है।

164  public String(String original) { 
    165   int size = original.count; 
    166   char[] originalValue = original.value; 
    167   char[] v; 
    168   if (originalValue.length > size) { 
    169    // The array representing the String is bigger than the new 
    170    // String itself. Perhaps this constructor is being called 
    171    // in order to trim the baggage, so make a copy of the array. 
    172    int off = original.offset; 
    173    v = Arrays.copyOfRange(originalValue, off, off+size); 
    174   } else { 
    175    // The array representing the String is the same 
    176    // size as the String, so no point in making a copy. 
    177    v = originalValue; 
    178   } 
    179   this.offset = 0; 
    180   this.count = size; 
    181   this.value = v; 

यह कुछ कई डेवलपर्स भूल है और क्योंकि एक छोटी सी स्ट्रिंग रोक सकता है महत्वपूर्ण है:

अभिव्यक्ति मैं का उपयोग करें, "सामान ट्रिम", स्ट्रिंग नकल निर्माता के स्रोत कोड से लिया जाता है एक बड़ा चार सरणी का कचरा। इस संबंधित प्रश्न को देखें जहां मैंने पहले ही यह इंगित किया है: Java not garbage collecting memory। कई डेवलपर्स जावा डिजाइनरों के निर्णय से इस पुराने अनुकूलन चाल का उपयोग करने के लिए विचार करते हैं जो सी कोडर्स से परिचित था, वास्तव में, अच्छे से ज्यादा नुकसान। हम में से कई इसे जानते हैं क्योंकि हमें इसकाट दिया गया था और यह समझने के लिए सूर्य के स्रोत कोड को देखना होगा ...

मार्को 7 अपडेट 6 से शुरू होने वाले ओपनजेडीके में मार्को बताते हैं (नीचे टिप्पणियां देखें) , substring अब चार सरणी साझा नहीं करता है और String(String) कन्स्ट्रक्टर, इस प्रकार बेकार है। लेकिन यह अभी भी तेज़ है (वास्तव में तेज़ी से भी) और चूंकि यह परिवर्तन सभी वीएम (और शायद आपके सभी ग्राहकों को) के लिए प्रचारित नहीं किया गया था, इसलिए मैं इस सर्वोत्तम अभ्यास को new String(substring) का उपयोग करने की सलाह दूंगा जब पुराना व्यवहार इसे उचित ठहरा रहा था ।

+5

... और यह ओपनजेडीके 7, अपडेट 6 के रूप में चला गया है। 'Substring',' trim' आदि के माध्यम से कोई और संरचनात्मक साझाकरण नहीं है –

+0

@Marko क्या आप उल्लेख किए गए अपडेट के स्रोत को इंगित कर सकते हैं? मुझे उस महत्वपूर्ण परिवर्तन से अवगत नहीं था। –

+3

[यहां पर संदर्भ] (http://hg.openjdk.java.net/jdk7u/jdk7u6/jdk/file/8c2c5d63a17e/src/share/classes/java/lang/String.java) मैंने पहले ही इसे बुकमार्क किया है, यह है जब से मैंने जॉन स्कीट से सीखा, तब से लोकप्रिय मांग में रहा! –

संबंधित मुद्दे