2011-01-28 16 views
24

मैं एक कक्षा में आया हूं जिसमें एक स्ट्रिंग शाब्दिक, "foo" के एकाधिक उपयोग शामिल हैं।अंतिम चर के बजाय समान स्ट्रिंग अक्षर का उपयोग करना?

मैं जानना चाहते हैं क्या, लाभ और प्रभाव इस दृष्टिकोण का उपयोग कर के बजाय अंतिम रूप स्ट्रिंग घोषित करने और अंतिम के साथ सभी शाब्दिक की जगह (ऑब्जेक्ट निर्माण, स्मृति के उपयोग और गति के मामले में) क्या कर रहे हैं है चर?

उदाहरण के लिए (हालांकि स्पष्ट रूप से नहीं एक असली शब्द उपयोग):

private static final String FINAL_STRING = "foo"; 

public void stringPrinter(){ 
    for(int i=0;i<10;i++){ 
     System.out.println(FINAL_STRING); 
    } 
} 

वर्सेज:

public void stringPrinter(){ 
    for(int i=0;i<10;i++){ 
     System.out.println("foo"); 
    } 
} 

कौन सा बेहतर है और क्यों (यह मानते हुए स्ट्रिंग मान स्थिर रहेंगे) क्या है?

उपर्युक्त (दूसरा) उदाहरण 10 स्ट्रिंग ऑब्जेक्ट्स बनने के परिणामस्वरूप होगा या JVM का एहसास होगा कि वास्तव में केवल एक अक्षर का उपयोग किया जाता है, और एक संदर्भ बनाते हैं। यदि हां, तो क्या स्ट्रिंग को अंतिम के रूप में घोषित करने का कोई फायदा है (जैसा कि पहले उदाहरण में है)?

व्याख्या कोड स्ट्रिंग एक भी संदर्भ के साथ शाब्दिक की जगह करता है, करता है अभी भी लागू है कि अगर एक ही शाब्दिक एक से अधिक स्थानों में होता है:

public void stringPrinter(){ 
    for(int i=0;i<5;i++){ 
     System.out.println("foo"); // first occurence 
     System.out.println("foo"); // second occurence 
    } 
} 
+0

मुझे लगता है कि पिछले डेवलपर ने स्थिरता का उपयोग करने पर शाब्दिक दोहराना चुना है, बस आलस्य की तरह लगता है। –

+0

आश्चर्यजनक रूप से, वे वास्तव में निरंतर घोषित करते थे लेकिन इसका उपयोग नहीं करते थे। इसलिए मुझे संभावित कारण में दिलचस्पी क्यों थी। लेकिन सहमत हो गया, मुझे लगता है कि यह सिर्फ आलस्य था। – Mikaveli

उत्तर

26

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

लाभ बनाए रखने में अधिक आता है। यदि आप शाब्दिक परिवर्तन करना चाहते हैं, तो आपको केवल एक घटना को स्थिरता के साथ बदलना होगा, लेकिन यदि आपको इनलाइन शामिल किया गया तो आपको प्रत्येक इंस्टेंस को खोजने और बदलने की आवश्यकता होगी।

+0

रखरखाव के बारे में अच्छा उल्लेख है। –

+0

सभी उत्तर बहुत उपयोगी थे, इसलिए आपका पहला होने के लिए स्वीकार कर लिया गया। – Mikaveli

20

From the JLS
प्रकार स्ट्रिंग की संकलन समय स्थिरांक हमेशा "प्रशिक्षु" जाता है कि उनको अद्वितीय उदाहरण हैं साझा करने के लिए, विधि String.intern का उपयोग कर।

तो, नहीं, केवल एक स्ट्रिंग ऑब्जेक्ट होने वाला है।

मार्क नोट्स के रूप में, यह सख्ती से रखरखाव का सवाल है और प्रदर्शन नहीं।

2

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

1

आपके द्वारा प्रदान किए जा रहे मामलों में, मेरा मानना ​​है कि इसे FINAL_STRING के रूप में घोषित करने का सबसे बड़ा कारण यह सुनिश्चित करना है कि यह एक केंद्रीकृत स्थान पर रहता है। उस स्ट्रिंग स्थिरता का केवल एक उदाहरण होगा, लेकिन पहला उदाहरण बनाए रखने के लिए कहीं अधिक आसान है।

3

सभी स्ट्रिंग शाब्दिक एक स्ट्रिंग कैश में रखा जाता है (यह सब वर्गों में है)

एक निरंतर का उपयोग कोड साफ कर सकते हैं, स्ट्रिंग कुछ संदर्भ देने के लिए और अगर एक ही esp बनाए रखने के लिए कोड को आसान बनाने के स्ट्रिंग कई स्थानों पर दिखाई देती है।

7

लाभ प्रदर्शन में नहीं है, लेकिन रखरखाव और विश्वसनीयता में है।

मुझे हाल ही में एक असली उदाहरण लेने दो। एक प्रोग्रामर ने एक फ़ंक्शन बनाया जिसने एक स्ट्रिंग पैरामीटर लिया जो लेनदेन के प्रकार की पहचान करता था। फिर कार्यक्रम में उन्होंने इस प्रकार के खिलाफ स्ट्रिंग की तुलना की। जैसा:

if (type.equals("stock")) 
{ ... do whatever ... } 

फिर वह इस समारोह कहा जाता है, यह मूल्य "शेयर" गुजर।

क्या आप पूंजीकरण में अंतर देखते हैं? मूल प्रोग्रामर ने भी नहीं किया। यह पता लगाने के लिए काफी सूक्ष्म बग साबित हुआ, क्योंकि दोनों लिस्टिंग को देखते हुए, पूंजीकरण में अंतर ने मुझे नहीं मारा।

, तो इसके बजाय वह एक अंतिम स्थिर की घोषणा की थी,

final static String stock="stock"; 

तब पहली बार वह बजाय "स्टॉक" के "शेयर" में पारित करने के लिए करने की कोशिश की, वह मिल गया है | एक संकलन समय त्रुटि का कहना है।

इस उदाहरण में बेहतर अभी भी एक enum बनाने के लिए किया गया होगा, लेकिन मान लें कि उसे वास्तव में एक आउटपुट फ़ाइल या कुछ करने के लिए स्ट्रिंग लिखना पड़ा था, इसलिए इसे एक स्ट्रिंग होना था।

अंतिम स्टैटिक्स का उपयोग देता है कम से कम x फायदे में:

(1) आप इसे गलत वर्तनी हैं, तो आप एक संकलन समय त्रुटि है, बजाय एक संभवतः-सूक्ष्म रन-टाइम त्रुटि मिलता है।

(2) एक स्थैतिक मूल्य को एक मीटिंग नाम असाइन कर सकता है। कौन सा अधिक सुबोध है:

if (employeeType.equals("R")) ... 

या

if (employeeType.equals(EmployeeType.RETIRED)) ... 

(3) एकाधिक संबंधित मूल्यों देखते हैं, तो आप अंतिम स्टैटिक्स के एक समूह एक साथ कार्यक्रम के शीर्ष पर, रख सकते हैं इस प्रकार भविष्य पाठकों को सूचित क्या सभी संभव मूल्य हैं। मेरे पास एक बार देखा गया है जब एक समारोह दो या तीन अक्षर के खिलाफ एक मूल्य की तुलना करता है। और यह मुझे आश्चर्य छोड़ देता है: क्या अन्य संभावित मूल्य हैं, या यह है? (बेहतर अभी भी एक enum होने के लिए बेहतर है, लेकिन यह एक और कहानी है।)

+0

+1 स्पष्ट, पूर्ण उत्तर और संदिग्ध अक्षरों को प्रतिस्थापित करने के लिए सार्थक नामों का उपयोग करके पठनीयता के संभावित लाभ का उल्लेख करना। – Mikaveli

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