कार्यक्रमों में उनके कोड में बहुत सारे स्ट्रिंग अक्षर शामिल होते हैं। जावा में, इन स्थिरांक को दक्षता के लिए स्ट्रिंग तालिका नामक किसी चीज़ में एकत्र किया जाता है। उदाहरण के लिए, यदि आप दस अलग-अलग स्थानों में स्ट्रिंग "Name: "
का उपयोग करते हैं, तो JVM (आमतौर पर) में उस स्ट्रिंग का केवल एक उदाहरण होता है और सभी दस स्थानों में जहां इसका उपयोग किया जाता है, संदर्भ सभी एक उदाहरण को इंगित करते हैं। यह स्मृति बचाता है।
यह अनुकूलन संभव है क्योंकि String
अपरिवर्तनीय है। यदि स्ट्रिंग को बदलना संभव था, तो इसे एक स्थान बदलना मतलब होगा कि यह दूसरे नौ में भी बदल जाएगा। यही कारण है कि स्ट्रिंग को बदलने वाला कोई भी ऑपरेशन एक नया उदाहरण देता है।
String s = "boink";
s.toUpperCase();
System.out.println(s);
यह boink
, नहीं BOINK
प्रिंट: यह यदि आप ऐसा करते है कि क्यों। एक ही char[]
पर विचारों, बस एक टुकड़ा का उपयोग करके अपने चरित्र डेटा के लिए एक ही अंतर्निहित char[]
करने के लिए java.lang.String
मई बिंदु के कई उदाहरण, दूसरे शब्दों में, वे अलग हो सकता है:
अब एक और मुश्किल सा सरणी का फिर, दक्षता के लिए एक अनुकूलन। substring()
विधि उन मामलों में से एक है जहां यह होता है।
- स्ट्रिंग
"Fred"
स्ट्रिंग तालिका से लिया जाता है: s1 = "Fred47";
//String s1: data=[ 'F', 'r', 'e', 'd', '4', '7'], offset=0, length=6
// ^........................^
s2 = s1.substring(2, 5);
//String s2: data=[ 'F', 'r', 'e', 'd', '4', '7'], offset=2, length=3
// ^.........^
// the two strings are sharing the same char[]!
अपने SCJP सवाल में, यह सब करने के लिए निर्भर करता है।
- स्ट्रिंग
"47"
स्ट्रिंग तालिका से लिया गया है।
- स्ट्रिंग
"Fred47"
विधि कॉल के दौरान बनाई गई है।// 1
- स्ट्रिंग
"ed4"
विधि कॉल के दौरान बनाई गई है, रूप "Fred47"
// 2
- ही समर्थन सरणी साझा करने स्ट्रिंग
"ED4"
विधि कॉल के दौरान बनाई गई है। // 3
s.toString()
कोई नया निर्माण नहीं करता है, यह केवल this
देता है।
एक यह सब के दिलचस्प बढ़त मामला: चुनें यदि आप एक बहुत लंबा स्ट्रिंग है कि क्या होता है, उदाहरण के लिए, इंटरनेट से ली गई एक वेब पेज, मान लें कि char[]
की लंबाई दो मेगाबाइट है करते हैं। यदि आप substring(0, 4)
लेते हैं, तो आपको एक नया स्ट्रिंग मिलता है जो दिखता है जैसे कि यह केवल चार वर्ण लंबा है, लेकिन यह अभी भी उन दो मेगाबाइट बैकिंग डेटा साझा करता है। असली दुनिया में यह सब सामान्य नहीं है, लेकिन यह स्मृति का एक बड़ा अपशिष्ट हो सकता है! (दुर्लभ) मामले में आप इसे किसी समस्या के रूप में चलाते हैं, तो आप नई, छोटी बैकिंग सरणी के साथ स्ट्रिंग बनाने के लिए new String(hugeString.substring(0, 4))
का उपयोग कर सकते हैं।
अंत में, intern()
पर कॉल करके रनटाइम पर स्ट्रिंग तालिका में एक स्ट्रिंग को मजबूर करना संभव है। इस मामले में मूल नियम: ऐसा मत करो। विस्तारित नियम: तब तक ऐसा न करें जब तक आप यह सुनिश्चित करने के लिए मेमोरी प्रोफाइलर का उपयोग नहीं करते हैं कि यह एक उपयोगी अनुकूलन है।
मैं कल्पना संकलक पहले दो बयानों इनलाइन और अंतिम (अनावश्यक) विधि कॉल निकाल देंगे। यह आपको "फ्रेड 47", "एड 4", "ईडी 4" के साथ छोड़ देता है। –
@ जेरेड 'एस * संकलन-समय निरंतर अभिव्यक्ति नहीं है * इसलिए ऐसा नहीं होता है। (कोड संकलित करें और 'javap -c', या यहां तक कि' तार 'का उपयोग करें। –
[जावा - कितने स्ट्रिंग ऑब्जेक्ट्स?] के संभावित डुप्लिकेट (http://stackoverflow.com/questions/17898236/java-how-many -स्ट्रिंग-ऑब्जेक्ट्स) –