2012-03-19 18 views
8

जावा में StringBuilder और StringBuffer के बीच अंतर अच्छी तरह से प्रलेखित हैं और touched upon in StackOverflow भी हैं।क्यों स्ट्रिंगबिल्डर और स्ट्रिंगबफर एक आम इंटरफ़ेस लागू नहीं करते हैं?

असल में, StringBuilder के बाद से यह StringBuffer के लिए एक तेजी से ड्रॉप-में स्थानापन्न के रूप में इरादा था काफी एक ही इंटरफ़ेस के साथ StringBuffer की एक गैर सिंक्रनाइज़ प्रति है,। उनका एपीआई व्यावहारिक रूप से समान है और वे वास्तव में वर्तमान जेडीके में पहुंच योग्य अमूर्त वर्ग के उप-वर्ग हैं।

एक बात जो मुझे आश्चर्य है, इसलिए, वे सार्वजनिक रूप से संबंधित नहीं हैं। StringBuilder के उप-वर्ग के रूप में दोनों वर्गों को एक सामान्य इंटरफ़ेस लागू करने या StringBuffer होने के कारण दोनों वर्गों के लिए साझा कोड के अस्तित्व की अनुमति होगी।

तो यह क्यों अलग हो गया? क्या ऐसा था कि प्रोग्रामर अनजाने में थ्रेड-असुरक्षित कोड के साथ थ्रेड-सुरक्षित मिश्रण नहीं करेंगे? या यह सिर्फ एक डिजाइन निरीक्षण था जो अब अनंत काल के अंत में विरासत में मिलेगा?

संपादित करें: मैं क्यों बातें इस तरह हैं पर अटकलें कर सकते हैं, लेकिन मैं एक वास्तविक निर्णय करने के लिए ठोस संदर्भ के लिए उम्मीद कर रहा हूँ, उदाहरण के लिए:

बातें स्पष्ट करना करने के लिए एक जेएसआर प्रक्रिया के दौरान। जो कुछ भी मेरे लिए कुछ प्रकाश डालेगा, वह ऐसी स्थिति है जो कभी-कभी कठिनाई का कारण बनती है।

संपादित करें 2:

तथ्य यह है कि दोनों वर्गों को लागू Appendable पूरी तरह से मेरे मन फिसल गया। शायद क्योंकि यह विशेष इंटरफ़ेस अधिकांश उद्देश्यों के लिए बेकार है - यह केवल एक ही वर्ण या तैयार वस्तु को जोड़ सकता है और यही वह है। ज्यादातर मामलों में यह Object के उप-वर्ग होने वाले दोनों वर्गों की तुलना में अधिक उपयोगी नहीं है।

संपादित करें 3:

मूल्यांकन पुस्तकालयों टीम द्वारा:

ठीक है, यहाँ a semi-official source से वास्तव में इस सवाल के लिए तर्क है

यह है डिजाइन द्वारा कि StringBuffer और StringBuilder कोई साझा सार्वजनिक सुपरटेप साझा करें। वे विकल्प होने का इरादा नहीं रखते हैं: एक गलती (स्ट्रिंगबफर) है, और दूसरा (स्ट्रिंगबिल्डर) प्रतिस्थापन है।

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

उत्तर

3

मेरे पास एक जेएसआर संदर्भ नहीं है लेकिन मेरे एक्सप से।

  • StringBuffer एक उपवर्ग केStringBuilderके रूप में किया जाता है प्रदर्शन के कारणों के के लिए एक अच्छा विचार नहीं: नीचे कुछ कारण हैं। StringBuffer थ्रेड सुरक्षित बनाने के लिए आपको प्रत्येक कॉल को StringBuilder पर मुखौटा करना होगा जो बहुत अधिक ओवरहेड है।

  • ऊपर बात करने के लिए जोड़ा जा रहा है, आप आगे अनुकूलन कर सकते हैं, तो आप एक वर्ग के आंतरिक भागों है कि कारण है कि जावा java.util.Collections.synchronized* apis से अधिक java.lang.concurrent जोड़ा है पर सीधा पहुँच है या नहीं। चूंकि अधिक प्रत्यक्ष पहुंच ऑप्टिमाइज़ेशन के लिए अधिक विकल्प देती है। इस बिंदु Reference from the IBM blog

  • इसके अलावा पहली बात करने के लिए जोड़ने का समर्थन करने, मुझे लगता है कि नहीं यह एक डिजाइन निरीक्षण के रूप में दोनों वर्गों final तो निश्चित रूप से वे न इन कक्षाओं subclassed होना चाहते हैं कर

  • समान इंटरफेस के संबंध में, दोनों वर्ग समान इंटरफ़ेस i.e Serializable, Appendable, CharSequence लागू करते हैं। तो वे ड्रॉप-इन प्रतिस्थापन हैं। एकमात्र चीज यह है कि वे एक आम इंटरफेस को लागू नहीं कर रहे हैं बल्कि इसके बजाय तीन आम इंटरफेस हैं। जो समझ में आता है, क्योंकि एक फूला हुआ इंटरफ़ेस रखने की आवश्यकता नहीं है जो तकनीकी रूप से वर्तमान इंटरफेस (Serializable, Appendable, CharSequence) का योग होगा।

संपादित करें:

  • बिंदु @MatthewFlaschen करने के लिए, वहाँ apis जो/डब्ल्यू StringBuffer और StringBuilder लेकिन लागू नहीं किया इंटरफेस में से किसी में ख ही कर रहे हैं रहे हैं। पिछड़ा संगतता के साथ यह और अधिक है। आप एक नया एपीआई जोड़ना चाहते हैं लेकिन इंटरफेस का इस्तेमाल कई अन्य वर्गों द्वारा किया जा रहा है, इसलिए एक इंटरफेस बदलना संभव नहीं हो सकता है। यह निर्णय लेने का एक अच्छा विचार है कि जावा लोगों ने बनाया होगा। तो मैं यह एक गलती नहीं कहूंगा।

संपादित करें 2:

साइड नोट: नोट करने के लिए एक और बात है कि StringBuffer 1.0 और 1.5 में StringBuilder में पेश किया गया था है। तो एपिस जो दोनों वर्गों में हैं लेकिन इंटरफेस में नहीं हैं बाद में इन कक्षाओं के निर्माण के समय पेश किए जाते हैं।

+0

विधियां हैं उदा। संलग्न करें (लंबा) जो दोनों वर्गों में हैं लेकिन इंटरफेस में से कोई भी नहीं। –

+0

हालांकि मुझे लगता है कि वेक्टर और ऐरेलिस्ट कैसे सार सूची का विस्तार करते हैं, स्ट्रिंगबफर और स्ट्रिंगबिल्डर एक समान सार वर्ग बढ़ा सकते हैं। मैंने नवीनतम स्रोत को नहीं देखा है, लेकिन स्ट्रिंगबिल्डर सिंक्रनाइज़ेशन से स्ट्रिंगबफर कम से कम चीर-ऑफ लग रहा था। –

+0

@MatthewFlaschen append() परिशिष्ट से है। –

2

वे वास्तव में Appendable लागू करते हैं।

मैं इस बात से सहमत नहीं हूं कि यह बेकार है।मेरे अनुभव में, स्ट्रिंगबिल्डर/स्ट्रिंगबफर उपयोग का एक बड़ा हिस्सा केवल तारों से निपट रहा है (जो CharSequence लागू करता है)। शेष के लिए, आप String.valueOf पर इसे पास करने से पहले String.valueOf पर कॉल कर सकते हैं।

यह सुविधाजनक होगा यदि कोई अन्य इंटरफ़ेस था जिसमें append(long) जैसी अन्य विधियां भी थीं। लेकिन यह जरूरी नहीं है।

एक सामान्य इंटरफ़ेस होना उचित होगा। उनके पास अलग-अलग प्रदर्शन और थ्रेडिंग विशेषताएं हैं, लेकिन जेडीके में कई इंटरफेस के बारे में यह ठीक और सच है।

उदाहरण के लिए, CopyOnWriteArrayList एक सरणी आधारित धागे की सुरक्षित सूची (यह हर लिखने के लिए एक नई सूची में आता है) में है, जबकि LinkedList एक गैर धागा सुरक्षित लिंक्ड सूची है।

+0

आपने इस सवाल का जवाब नहीं दिया है, या यहां तक ​​कि कोई अंतर्दृष्टि भी दे सकती है कि यह क्यों हो सकता है। – FriendlyGuy

+0

@ मैकी खान, मैं असहमत हूं। मैंने कहा "एक सामान्य इंटरफ़ेस होना उचित होगा।", यह कहने का एक और तरीका है, "हां, यह एक डिजाइन निरीक्षण है"। –

+0

ईमानदारी से, परिशिष्ट मेरे दिमाग फिसल गया, ज्यादातर क्योंकि मैं नियमित रूप से संख्या e.t.c. संलग्न करता हूं। मेरे कोड में मुझे वास्तव में यह विशेष इंटरफ़ेस बहुत उपयोगी नहीं लगता है, क्योंकि यह आपको सबकुछ पहले से स्ट्रिंग में बदलने के लिए मजबूर करता है। उल्लेख नहीं है कि मौजूदा सामग्री अपरिवर्तनीय है ... – thkala