2012-11-08 12 views
137

आप विधि पर enum एपीआई में देखें, तो name() यह कहा गया है कि:जावा enum - क्यों उपयोग toString के बजाय नाम

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

toString() का उपयोग करना बेहतर क्यों है? मेरा मतलब है toString अधिरोहित जा सकता है जब नाम() पहले से ही अंतिम है। तो यदि आप ToString का उपयोग करते हैं और कोई हार्ड कोड कोड को वापस करने के लिए इसे ओवरराइड करता है तो आपका पूरा एप्लिकेशन डाउन हो जाता है ... यदि आप स्रोतों को देखते हैं तो ToString() विधि बिल्कुल और केवल नाम लौटाती है। एक ही बात है।

+3

आप अपने enum में 'toString()' को ओवरराइड कर सकते हैं, लेकिन कोई भी इसे बढ़ा और ओवरराइड नहीं कर सकता है। आप enums का विस्तार नहीं कर सकते हैं। –

उत्तर

157

यह वास्तव में क्या आप दिए गए मान के साथ क्या करना चाहते हैं पर निर्भर करता है:

  • आप सटीक निरंतर enum घोषित करने के लिए उपयोग किया गया नाम प्राप्त करने की आवश्यकता है, तो आप का उपयोग करना चाहिए name() रूप toString हो सकता है ओवरराइड दिया
  • आप एक उपयोगकर्ता के अनुकूल तरीके से enum निरंतर मुद्रित करने के लिए, आप toString जो ओवरराइड गया हो सकता है का उपयोग करना चाहिए चाहते हैं (या नहीं!)।

जब मुझे लगता है कि यह भ्रामक हो सकता है, मैं एक अधिक विशिष्ट getXXX विधि प्रदान करते हैं, उदाहरण के लिए:

41

name() का उपयोग करें जब आप तुलना करना चाहते हैं या अपने कोड में कुछ आंतरिक उपयोग के लिए हार्डकोडेड मान का उपयोग करना चाहते हैं।

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

जावाडोक (जोर मेरा) से:

वस्तु के एक स्ट्रिंग प्रतिनिधित्व देता है। सामान्य तौर पर, toString विधि एक स्ट्रिंग है "टेक्स्ट रूप का प्रतिनिधित्व करता है" इस वस्तु देता है। परिणाम एक संक्षिप्त लेकिन सूचनात्मक प्रतिनिधित्व पढ़ने के लिए एक व्यक्ति के लिए आसान है कि होना चाहिए। यह अनुशंसा की जाती है कि सभी सबक्लास इस विधि को ओवरराइड करें।

18

name() एक "निर्मित" enum की विधि है। यह अंतिम है और आप इसके कार्यान्वयन को नहीं बदल सकते हैं। यह एनम स्थिरांक का नाम देता है जैसा लिखा है, उदा। ऊपरी मामले में, रिक्त स्थान आदि के बिना

MOBILE_PHONE_NUMBER और Mobile phone number की तुलना करें। कौन सा संस्करण अधिक पठनीय है? मुझे दूसरा विश्वास है।यह अंतर है: name() हमेशा MOBILE_PHONE_NUMBER लौटाता है, toString()Mobile phone number लौटने के लिए अतिप्रवाह हो सकता है।

+15

यह सही नहीं है !! toString() केवल 'मोबाइल फोन नंबर' देता है यदि आप इस तरह के मान को वापस करने के लिए इसे ओवरराइड करते हैं। अन्यथा यह 'MOBILE_PHONE_NUMBER' – spauny

+1

@spayny वापस कर देगा, यह स्पष्ट है कि आपको' toString() 'को ओवरराइड करना होगा। पकड़ यह है कि अंतिम नाम होने के बाद 'नाम() 'ओवरराइड नहीं किया जा सकता है। – AlexR

+12

@AlexR आपको 100% सही – artfullyContrived

4

नाम() सचमुच enum के जावा कोड में पाठ का नाम है। इसका मतलब है कि यह तारों तक ही सीमित है जो वास्तव में आपके जावा कोड में दिखाई दे सकते हैं, लेकिन कोड में सभी वांछनीय तार स्पष्ट नहीं हैं। उदाहरण के लिए, आपको एक स्ट्रिंग की आवश्यकता हो सकती है जो किसी संख्या से शुरू होती है। नाम() आपके लिए उस स्ट्रिंग को कभी भी प्राप्त नहीं कर पाएगा।

3

एक व्यावहारिक उदाहरण जब नाम() और toString() अलग होने के लिए समझ में आता है वह पैटर्न है जहां सिंगल-वैल्यूड एनम का उपयोग सिंगलटन को परिभाषित करने के लिए किया जाता है। यह पहली बार आश्चर्यजनक रूप से दिखता है, लेकिन भावना का एक बहुत बनाता है:

enum SingletonComponent { 
    INSTANCE(/*..configuration...*/); 

    /* ...behavior... */ 

    @Override 
    String toString() { 
     return "SingletonComponent"; // better than default "INSTANCE" 
    } 
} 

इस तरह के मामले में:

SingletonComponent myComponent = SingletonComponent.INSTANCE; 
assertThat(myComponent.name()).isEqualTo("INSTANCE"); // blah 
assertThat(myComponent.toString()).isEqualTo("SingletonComponent"); // better 
+0

हाँ, आप सही हैं ... एक अच्छा उदाहरण है गुवा की enum भविष्यवाणी – spauny

11

हालाँकि अधिकांश लोग आँख बंद करके जावाडोक की सलाह का पालन, वहाँ बहुत विशिष्ट स्थितियों में, जहां आप करना चाहते हैं वास्तव में toString() से बचें। उदाहरण के लिए, मैं अपने जावा कोड में enums का उपयोग कर रहा हूं, लेकिन उन्हें डेटाबेस में क्रमबद्ध करने की आवश्यकता है, और फिर से वापस। अगर मैं toString() का उपयोग करता था तो मैं तकनीकी रूप से ओवरराइड व्यवहार प्राप्त करने के अधीन रहूंगा जैसा कि दूसरों ने इंगित किया है।

इसके अतिरिक्त एक भी डी-serialize कर सकते हैं डेटाबेस से, उदाहरण के लिए, यह हमेशा जावा में काम करना चाहिए:

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.name());

जबकि इस गारंटी नहीं है:

MyEnum taco = MyEnum.valueOf(MyEnum.TACO.toString());

तक वैसे, मुझे जवाडोक के लिए यह स्पष्ट रूप से कहना है कि "अधिकांश प्रोग्रामर चाहिए"। मुझे एक enum के toString में बहुत कम उपयोग-मामले मिलते हैं, अगर लोग इसे "दोस्ताना नाम" के लिए उपयोग कर रहे हैं जो स्पष्ट रूप से खराब उपयोग-मामला है क्योंकि उन्हें i18n के साथ कुछ और संगत उपयोग करना चाहिए, जो कि ज्यादातर मामलों में, नाम() विधि का प्रयोग करें।

+2

उत्तर देने के लिए धन्यवाद। यह सवाल पूछने के लगभग 5 साल हो गए हैं और मैंने अभी तक enum के लिए toString() विधि का उपयोग नहीं किया है! 99% बार मैं आपके द्वारा वर्णित शब्दों के लिए बिल्कुल उपयोग करता हूं: डेटाबेस से/से क्रमशः enial नामों को क्रमबद्ध करना और deserialising। – spauny

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