2010-01-05 11 views
85

हम आम तौर पर new कीवर्ड का उपयोग, जैसे वस्तुओं को बनाने:स्ट्रिंग जावा में ऑब्जेक्ट्स हैं, तो हम उन्हें बनाने के लिए 'नया' क्यों नहीं उपयोग करते हैं?

Object obj = new Object(); 

स्ट्रिंग्स वस्तुओं रहे हैं, फिर भी हम new का उपयोग नहीं करते उन्हें बनाने के लिए:

String str = "Hello World"; 

ऐसा क्यों है? क्या मैं new के साथ स्ट्रिंग कर सकता हूं?

+0

आपको इस प्रश्न पर भी गौर करना चाहिए http://stackoverflow.com/questions/456575/java-wrapper- समानता परीक्षण – changed

+1

क्योंकि स्ट्रिंग अक्षर पहले से ही ऑब्जेक्ट्स हैं। – EJP

+0

ध्यान दें कि 'नई स्ट्रिंग (...) 'का उपयोग बड़े तारों को प्रतिस्थापित करते समय कार्यान्वयन विस्तार को रोकने के लिए किया गया है। यह जावा 7 में तय किया गया था और अब और आवश्यक नहीं है। –

उत्तर

113

क्या पहले से ही कहा गया था के अलावा, स्ट्रिंग शाब्दिक [यानी, "abcd" लेकिन नहीं की तरह तार की तरह new String("abcd")] जावा में प्रशिक्षु रहे हैं - इसका मतलब यह है कि हर बार जब आप का उल्लेख "एबीसीडी" करने के लिए, आप एक के लिए एक संदर्भ मिल प्रत्येक बार एक नए के बजाय एकल String उदाहरण। तो तुम होगा:

String a = "abcd"; 
String b = "abcd"; 

a == b; //True 

लेकिन अगर आप

String a = new String("abcd"); 
String b = new String("abcd"); 

था तो यह

a == b; // False 

(और मामले में किसी को भी याद दिलाने की जरूरत है, हमेशा .equals() का उपयोग स्ट्रिंग्स की तुलना करने के लिए संभव है; भौतिक समानता के लिए == परीक्षण)।

आंतरिक स्ट्रिंग अक्षर अच्छा है क्योंकि उन्हें अक्सर एक से अधिक बार उपयोग किया जाता है। उदाहरण के लिए, (काल्पनिक) कोड पर विचार करें:

for (int i = 0; i < 10; i++) { 
    System.out.println("Next iteration"); 
} 

हम स्ट्रिंग्स का होना शामिल नहीं था, तो "अगली यात्रा" 10 बार instantiated जा करने के लिए है, जबकि अब यह केवल एक बार instantiated हो जाएगा की आवश्यकता होगी।

+1

स्ट्रिंग ए = नई स्ट्रिंग ("abcd") का उपयोग करके, इसका मतलब है कि समान सामग्री वाले दो स्ट्रिंग स्मृति में मौजूद हैं। – changed

+1

दाएं - संकलक यह देखने के लिए जरूरी नहीं है कि ऐसा स्ट्रिंग पहले से ही इंटर्न किया गया है (हालांकि आप निश्चित रूप से ऐसा लिख ​​सकते हैं)। – danben

+0

हां, यह अनुकूलन संभव है क्योंकि तार अपरिवर्तनीय हैं और इसलिए समस्याओं के बिना साझा किया जा सकता है। साझा "asdf" हैंडलिंग 'फ्लाईवेट' डिज़ाइन पैटर्न का कार्यान्वयन है। –

6

यह एक शॉर्टकट है। यह मूल रूप से ऐसा नहीं था, लेकिन जावा ने इसे बदल दिया।

यह FAQ इसके बारे में संक्षेप में बात करता है। जावा विशिष्टता मार्गदर्शिका इसके बारे में भी बात करती है। लेकिन मुझे यह ऑनलाइन नहीं मिल रहा है।

+2

टूटा लिंक, और मुझे किसी अन्य सबूत के बारे में पता नहीं है कि यह कभी बदला गया था। – EJP

+1

@EJP यह अभी भी [वेबैक मशीन] में है (http://web.archive.org/web/20130423122845/http://www.codestyle.org/java/faq-Strings.shtml#stringconstructor) यदि यह उपयोगी है। – Arjan

0

String s = new String("I'm a new String"); 

सामान्य अंकन s = "new String"; है के साथ एक नया स्ट्रिंग बनाने के लिए स्वतंत्र महसूस अधिक या कम एक सुविधाजनक शॉर्टकट - जो उन बहुत दुर्लभ मामलों में, के अलावा प्रदर्शन के कारणों के लिए किया जाना चाहिए जहां वास्तव में स्ट्रिंग्स कि समीकरण

(string1.equals(string2)) && !(string1 == string2) 

संपादित

के लिए अर्हता प्राप्त की जरूरत है

टिप्पणी के जवाब में: यह एक सलाह होने का इरादा नहीं था, लेकिन प्रश्नकर्ता थीसिस के लिए केवल एक सीधी प्रतिक्रिया है, हम स्ट्रिंग्स के लिए 'नया' कीवर्ड का उपयोग नहीं करते हैं, जो कि बस ' सच नहीं है उम्मीद है कि इस संपादन (उपर्युक्त सहित) इसे थोड़ा सा स्पष्ट करता है। बीटीडब्ल्यू - एसओ पर उपर्युक्त प्रश्न के कुछ अच्छे और बेहतर उत्तर हैं।

+4

-1 - खराब सलाह। आपको 'नई स्ट्रिंग (...)' का उपयोग करने के लिए "स्वतंत्र महसूस नहीं करना चाहिए" अपने आवेदन को अनलाने के लिए आपको एक अलग पहचान के साथ एक स्ट्रिंग बनाने की आवश्यकता है। –

+1

मुझे पता है कि। स्पष्टीकरण के लिए पद संपादित किया। –

6

स्ट्रिंग कुछ अनुकूलन (बेहतर वाक्यांश की इच्छा के लिए) के अधीन है। ध्यान दें कि स्ट्रिंग में ऑपरेटर ओवरलोडिंग (+ ऑपरेटर के लिए) है - अन्य ऑब्जेक्ट्स के विपरीत। तो यह बहुत खास मामला है।

+1

द + वास्तव में एक ऑपरेटर है जिसका अनुवाद स्ट्रिंगबिल्डर .append (..) कॉल में किया जाता है। – whiskeysierra

0

सिंटेक्टिक चीनी।

String s = new String("ABC"); 

वाक्यविन्यास अभी भी उपलब्ध है।

+1

यह बिल्कुल सही नहीं है। एस = नया स्ट्रिंग ("एबीसी") आपको एस = "एबीसी" के समान परिणाम नहीं देगा। डैनबेन की टिप्पणी देखें। –

+2

इसके अलावा, कुछ हद तक विडंबना यह है कि यह पहले "एबीसी" इनलाइन का प्रतिनिधित्व करने वाला एक स्ट्रिंग उदाहरण बना देगा - और उसके बाद इसे कन्स्ट्रक्टर कॉल के लिए एक तर्क के रूप में पास करेगा जो एक समान मूल्य की स्ट्रिंग को वापस लाएगा। –

+1

इस कन्स्ट्रक्टर के लिए वैध उपयोग केस 'स्ट्रिंग छोटा = नया स्ट्रिंग (huge.substring (int, int)) है;', जो आपको मूल 'विशाल' स्ट्रिंग से बड़े अंतर्निहित 'char [] 'को रीसायकल करने की अनुमति देता है। –

0

आप अभी भी new String("string") का उपयोग कर सकते हैं, लेकिन स्ट्रिंग अक्षर के बिना नए तारों को बनाना कठिन होगा ... आपको चरित्र सरणी या बाइट्स का उपयोग करना होगा :-) स्ट्रिंग अक्षर में एक अतिरिक्त संपत्ति है: सभी समान स्ट्रिंग अक्षर क्लास पॉइंट एक ही स्ट्रिंग इंस्टेंस (वे इंटर्न किए गए हैं)।

26

स्ट्रिंग जावा में "विशेष" ऑब्जेक्ट्स हैं। जावा डिजाइनरों ने बुद्धिमानी से निर्णय लिया कि स्ट्रिंग्स का उपयोग अक्सर किया जाता है कि उन्हें अपने स्वयं के वाक्यविन्यास के साथ-साथ एक कैशिंग रणनीति की आवश्यकता होती है। जब आप कहकर स्ट्रिंग घोषित करते हैं:

String myString = "something"; 

myString "कुछ" के मान के साथ स्ट्रिंग ऑब्जेक्ट का संदर्भ है। आप बाद में यह घोषणा करते हैं:

String myOtherString = "something"; 

जावा बहुत चालाक बाहर काम करने कि myString और myOtherString ही कर रहे हैं और एक ही वस्तु के रूप में एक वैश्विक स्ट्रिंग तालिका में संग्रहीत नहीं है। यह इस तथ्य पर निर्भर करता है कि आप ऐसा करने के लिए स्ट्रिंग्स को संशोधित नहीं कर सकते हैं। यह आवश्यक स्मृति की मात्रा को कम करता है और तुलना तेजी से कर सकता है।

, तो इसके बजाय, आपके द्वारा लिखी

String myOtherString = new String("something"); 

जावा आप के लिए एक नया वस्तु, myString वस्तु से अलग पैदा करेगा।

+0

अरे ... स्ट्रिंग अक्षर के लिए किसी प्रकार के वाक्य रचनात्मक समर्थन की आवश्यकता को पहचानने के लिए इसे "अनंत ज्ञान" की आवश्यकता नहीं है। बस हर दूसरे गंभीर प्रोग्रामिंग भाषा डिजाइन के बारे में कुछ प्रकार के स्ट्रिंग शाब्दिक का समर्थन करता है। –

+10

हाइपरबोले को कम करने के लिए कम कर दिया गया है, कप्तान :) –

1

जावा में, स्ट्रिंग्स एक विशेष मामला है, जिसमें कई नियम केवल स्ट्रिंग्स पर लागू होते हैं। डबल कोट्स कंपाइलर को स्ट्रिंग ऑब्जेक्ट बनाने का कारण बनता है। चूंकि स्ट्रिंग ऑब्जेक्ट्स अपरिवर्तनीय हैं, इसलिए यह कंपाइलर को कई तारों को प्रशिक्षित करने की अनुमति देता है, और एक बड़ा स्ट्रिंग पूल बनाता है। दो समान स्ट्रिंग स्थिरांक हमेशा एक ही ऑब्जेक्ट संदर्भ होगा। यदि आप यह मामला नहीं चाहते हैं, तो आप नए स्ट्रिंग ("") का उपयोग कर सकते हैं, और यह रनटाइम पर एक स्ट्रिंग ऑब्जेक्ट बनाएगा। स्ट्रिंग लुकअप टेबल के विरुद्ध गतिशील रूप से बनाए गए तारों को जांचने के लिए इंटर्न() विधि सामान्य होती थी। एक बार इंटर्न में एक स्ट्रिंग, ऑब्जेक्ट संदर्भ कैननिकल स्ट्रिंग इंस्टेंस को इंगित करेगा।

String a = "foo"; 
    String b = "foo"; 
    System.out.println(a == b); // true 
    String c = new String(a); 
    System.out.println(a == c); // false 
    c = c.intern(); 
    System.out.println(a == c); // true 

जब क्लासलोडर कक्षा को लोड करता है, तो सभी स्ट्रिंग स्थिरांक स्ट्रिंग पूल में जोड़े जाते हैं।

0

शाब्दिक (कोट्स में वर्ण) के रूप में स्ट्रिंग ऑब्जेक्ट की लगभग कोई आवश्यकता नहीं है, मेजबान वर्ग लोड होने पर पहले से ही एक स्ट्रिंग ऑब्जेक्ट बनाया गया है। शाब्दिक और डॉन पर विधियों का आह्वान करना पूरी तरह से कानूनी है, मुख्य भेद साहित्य द्वारा प्रदान की जाने वाली सुविधा है। यह एक बड़ा दर्द और टाइन का अपशिष्ट होगा यदि हमें चार्जों की एक सरणी बनाना था और इसे चार से चार भरना था और वे एक नया स्ट्रिंग (चार सरणी) कर रहे थे।

0

शाब्दिक पूल में कोई भी स्ट्रिंग शामिल है जो कीवर्ड new का उपयोग किये बिना बनाई गई थी।

एक अंतर है: नए संदर्भ के बिना स्ट्रिंग को स्ट्रिंग शाब्दिक पूल में संग्रहित किया जाता है और स्ट्रिंग नए कहते हैं कि वे ढेर मेमोरी में हैं।

नए के साथ स्ट्रिंग किसी भी अन्य वस्तु की तरह स्मृति में कहीं और हैं।

14
String a = "abc"; // 1 Object: "abc" added to pool 

String b = "abc"; // 0 Object: because it is already in the pool 

String c = new String("abc"); // 1 Object 

String d = new String("def"); // 1 Object + "def" is added to the Pool 

String e = d.intern(); // (e==d) is "false" because e refers to the String in pool 

String f = e.intern(); // (f==e) is "true" 

//Total Objects: 4 ("abc", c, d, "def"). 

आशा है कि इससे कुछ संदेह साफ हो जाएंगे। :)

+0

स्ट्रिंग डी = नया स्ट्रिंग ("डीफ़"); // 1 ऑब्जेक्ट + "डीफ़" पूल में जोड़ा गया है -> यहां "डीफ़" पूल में जोड़ा जाएगा, अगर यह अभी तक – southerton

+0

@ सॉटरटन अर्थहीन नहीं है। यह पहले से ही पूल में है। यह कंपाइलर द्वारा वहां रखा गया था। – EJP

+0

अंत में, कुछ स्पष्ट और जानकारीपूर्ण! – Satyam

0

क्योंकि स्ट्रिंग जावा में एक अपरिवर्तनीय वर्ग है।

अब यह अपरिवर्तनीय क्यों है? जैसा स्ट्रिंग अपरिवर्तनीय है, इसलिए इसे कई धागे के बीच साझा किया जा सकता है और हमें स्ट्रिंग ऑपरेशन को बाहरी रूप से सिंक्रनाइज़ करने की आवश्यकता नहीं है। जैसा कि स्ट्रिंग का उपयोग कक्षा लोडिंग तंत्र में भी किया जाता है।

यह सच है, दोनों

मैं दो अलग-अलग ऑब्जेक्ट का निर्माण: तो अगर स्ट्रिंग फिर परिवर्तनशील था java.io.writer

0
TString obj1 = new TString("Jan Peter");     
TString obj2 = new TString("Jan Peter");      

if (obj1.Name == obj2.Name)     
    System.out.println("True"); 
else     
    System.out.println("False"); 

आउटपुट abc.xyz.mywriter करने के लिए बदल किया जा सकता था एक क्षेत्र (रेफरी) 'नाम' है। तो इस मामले में भी "जन पीटर" साझा किया जाता है, अगर मैं जावा सौदों के तरीके को समझता हूं ..