2015-04-26 12 views
14

मैं वास्तव में जावा में काम करता हूं कि कैसे string interning काम करता है। जब मैं लिखता हूं:जावा में संकलन समय पर स्ट्रिंग इंटर्निंग किया जाता है?

String a = "ABC"; 
String b = "ABC"; 

if (a==b) 
    System.out.println("Equal"); 

क्या कंपाइलर संकलन समय पर स्ट्रिंग निरंतर पूल में स्ट्रिंग अक्षर "एबीसी" स्टोर करता है?

यह अजीब लगता है, क्योंकि मैंने सोचा था कि स्ट्रिंग निरंतर पूल रनटाइम पर जेवीएम द्वारा बनाया गया था, और मुझे नहीं लगता कि यह संकलन समय पर किया जाता है यदि जावा कंपाइलर JVM भी नहीं बुलाता है ।

यह संकलन समय पर नहीं किया जाता है और यह क्रम तो क्यों निम्नलिखित वापसी झूठी (this answer से लिया गया) करता है पर किया जाता है?

// But .substring() is invoked at runtime, generating distinct objects 
"test" == "!test".substring(1) // --> false 

यदि यह रनटाइम पर किया जाता है तो JVM क्यों नहीं समझ सकता कि वे एक ही स्ट्रिंग हैं?

मैं वास्तव में उलझन में हूं कि जावा में स्ट्रिंग इंटर्निंग कैसे काम करती है और जहां वास्तव में जावा स्ट्रिंग पूल संग्रहीत किया जाता है।

+0

नीचे दिए गए लिंक व्यावहारिक है: http://stackoverflow.com/questions/513832/ How-do-i-compar-strings-in-java – Zyn

+0

मुझे आपके प्रश्न के पहले भाग के बारे में निश्चित नहीं है, लेकिन 'substring' एक * नया * ऑब्जेक्ट देता है, और इसलिए दोनों तारों की सामग्री' परीक्षण से मेल खाती है ', चूंकि वे एक ही वस्तु नहीं हैं' == 'झूठी रिटर्न। –

+2

यह संकलक है। मुझे समझ में नहीं आता कि आप क्यों कहते हैं कि यह तार स्ट्रिंग निरंतर पूल में स्ट्रिंग नहीं डाल सकता है।कंपाइलर कुछ मेमोरी लोकेशन के अंदर लगातार स्ट्रिंग रखेगा, फिर प्रोग्राम लॉन्च करते समय जेवीएम उस मेमोरी को लोड करेगा और रनटाइम पर इस्तेमाल होने वाले निरंतर पूल को बनाएगा, लेकिन पूल कंपाइलर द्वारा स्थापित किया जाएगा। – Bakuriu

उत्तर

18

कंपाइलर कक्षा फ़ाइल में शाब्दिक तार रखता है (और केवल अद्वितीय, यह समकक्ष सभी समकक्षों को समेकित करता है); कक्षा फ़ाइल लोड होने पर JVM स्ट्रिंग पूल में उन तारों को लोड करता है।

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

क्योंकि स्ट्रिंग .substring द्वारा दिया जा रहा है प्रशिक्षु नहीं किया गया है, और इसलिए स्ट्रिंग पूल में बराबर "test" स्ट्रिंग तुलना में एक अलग वस्तु है। आप इसे प्रशिक्षु हैं, तो आप true मिल चाहते हैं:

"test" == "!test".substring(1).intern() // true 

धारा §4.4 of the JLS और §5.3 of the JVM spec प्रासंगिक लग रहे हो।


बस स्पष्ट होना: जावा में तार की तुलना करने का सही तरीका .equals विधि या इसी तरह, नहीं == उपयोग करने के लिए है। स्ट्रिंग इंस्टेंस के साथ == का उपयोग आमतौर पर गलत है।

+1

@ http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#substring(int को प्रतिस्थापित करने के लिए प्रलेखन विशेष रूप से यह बताता है कि यह एक * नई * स्ट्रिंग ऑब्जेक्ट देता है। –

+0

बस कुछ विवरण जोड़ना। अच्छा उत्तर। –

+0

@ टीजेड्रोडर इसलिए 'इंटर्न()' नया ऑब्जेक्ट सही से बचाता है? –

0

(जब तक आप समझ कब और कैसे चीजों को प्रशिक्षु रहे हैं ... साथ खेल रहे हैं) मैं के लिए

String a = "ABC"; 
String b = "ABC"; 

.class की जाँच की और उस में केवल एक "एबीसी" पाया। वह जावैक संकलन समय पर एक ही स्ट्रिंग का एक स्थिर बनाता है।

लेकिन अगर 2 या अधिक वर्गों में एक ही "एबीसी" निरंतर तो JVM स्ट्रिंग पूल में एक ही स्थान पर रख दें होगा

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