सार्वजनिक स्थिर अंतिम क्षेत्रों के साथ एक वर्ग बनाम जावा एनम का क्या फायदा है?


147

मैं C # से बहुत परिचित हूं लेकिन जावा में अधिक काम करना शुरू कर रहा हूं। मुझे यह जानने की उम्मीद है कि जावा में एनम मूल रूप से सी # में उन लोगों के बराबर थे, लेकिन स्पष्ट रूप से यह मामला नहीं है। प्रारंभ में मैं यह जानने के लिए उत्साहित था कि जावा एनम में डेटा के कई टुकड़े हो सकते हैं जो बहुत फायदेमंद लगते हैं ( http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html )। हालाँकि, तब से मुझे बहुत सारी सुविधाएँ याद आ रही हैं जो C # में तुच्छ हैं, जैसे कि एक enum तत्व को एक निश्चित मान को आसानी से असाइन करने की क्षमता, और परिणामस्वरूप एक सभ्य राशि को प्रयास के बिना एक एनम में पूर्णांक में परिवर्तित करने की क्षमता (आदि) यानी जावा एनम से मेल करने के लिए पूर्णांक मान बदलें )।

तो मेरा सवाल यह है: क्या सार्वजनिक स्थिर अंतिम क्षेत्रों के झुंड के साथ एक वर्ग पर जावा एनमों का कोई लाभ है? या यह सिर्फ अधिक कॉम्पैक्ट वाक्यविन्यास प्रदान करता है?

संपादित करें: मुझे और अधिक स्पष्ट होने दें। एक ही प्रकार के सार्वजनिक स्थिर अंतिम क्षेत्रों के एक समूह के साथ एक वर्ग पर जावा एनमों का क्या लाभ है ? उदाहरण के लिए, पहले लिंक पर ग्रहों के उदाहरण में, इन सार्वजनिक स्थिरांक के साथ एक वर्ग पर एक दुश्मनी का क्या फायदा है:

public static final Planet MERCURY = new Planet(3.303e+23, 2.4397e6);
public static final Planet VENUS = new Planet(4.869e+24, 6.0518e6);
public static final Planet EARTH = new Planet(5.976e+24, 6.37814e6);
public static final Planet MARS = new Planet(6.421e+23, 3.3972e6);
public static final Planet JUPITER = new Planet(1.9e+27, 7.1492e7);
public static final Planet SATURN = new Planet(5.688e+26, 6.0268e7);
public static final Planet URANUS = new Planet(8.686e+25, 2.5559e7);
public static final Planet NEPTUNE = new Planet(1.024e+26, 2.4746e7);

जहाँ तक मैं बता सकता हूँ, कैसबेलैंका का जवाब केवल यही है जो इसे संतुष्ट करता है।


4
@ बोहेमियन: यह एक डुप्लिकेट नहीं हो सकता है, क्योंकि ओपी केवल उल्लेखित public static finalफ़ील्ड है, जो टाइप किए गए मान हो सकते हैं और जरूरी नहीं कि intएस।
कैसाब्लांका

1
@ शाजेब मुश्किल से। स्पष्ट रूप से स्ट्रिंग स्थिरांक के बजाय एनम का उपयोग करना एक अच्छा विचार है और प्रोत्साहित से अधिक है। टाइप-सेफ्टी, स्टैटिक यूटिलिटी फंक्शंस की जरूरत नहीं है, और इसी तरह .. इसके बजाय स्ट्रिंग्स का उपयोग करने का कोई कारण नहीं है।
वू व

1
@Voo हाँ मुझे पता था कि असहमति होगी। और यहाँ 49 सेकंड में एक है। एनम महान हैं (और मैं उन्हें प्यार करता हूं और उन्हें बहुत बार उपयोग करता हूं) लेकिन एक निरंतरता की घोषणा करते समय या इसका उपयोग करते समय आपको किस प्रकार की सुरक्षा की आवश्यकता होती है। यह हर बार जब आप स्ट्रिंग शाब्दिक के लिए एक निरंतर घोषित करने की जरूरत है, तो एनम बनाने के लिए एक ओवरकिल है।
शाहजेब

4
@ शाजेब यदि आपके पास एक एकल चर है, तो निश्चित रूप से एक स्ट्रिंग का उपयोग करें, यहां बहुत कुछ नहीं हो सकता है (एक मान एक पैरामीटर के रूप में व्यर्थ है)। लेकिन ध्यान दें कि हम स्थिरांक के बारे में बात कर रहे हैं S, इसलिए अब हम संभवतः उन्हें कार्यों में पारित करने के बारे में बात कर रहे हैं, आदि क्या हमें टाइप-सफ़टी की आवश्यकता है ? ठीक है, नहीं, लेकिन फिर ज्यादातर लोग "सब कुछ एक void*अच्छी शैली" के सी-शैली प्रकारों पर विचार करते हैं और यह बग को रोक सकता है (विशेषकर यदि एक से अधिक एनुम / स्ट्रिंग पैरामीटर पारित कर रहा है!)। इसके अलावा यह स्थिरांक को अपने स्वयं के नामस्थान आदि में रखता है, इसके विपरीत, केवल सादे चर रखने का कोई वास्तविक लाभ नहीं है।
वू

3
@ बोहेमियन: मैं नहीं देखता कि कैसे। intएस के साथ , कोई प्रकार की सुरक्षा नहीं है क्योंकि कोई भी मूल्य पारित कर सकता है। दूसरी ओर, टाइप की गई वस्तुएं, प्रकार की सुरक्षा के मामले में इनम से अलग नहीं हैं।
कैसाब्लांका

जवाबों:


78

तकनीकी रूप से कोई वास्तव में टाइप किए गए स्थिरांक के झुंड के साथ एक वर्ग के रूप में enums देख सकता है, और यह वास्तव में है कि आंतरिक रूप से एनम स्थिरांक को कैसे लागू किया जाता है। enumहालाँकि किसी का उपयोग करने से आपको उपयोगी तरीके ( Enum javadoc ) मिलते हैं जो आपको अन्यथा खुद को लागू करना होगा, जैसे कि Enum.valueOf


14
भी है .values()मानों की सूची से अधिक पुनरावृति करने के लिए।
h3xStream

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

7
@ आपकी प्रवृत्ति सही है - यह एक बहुत बुरा जवाब है, क्योंकि यह पूरी तरह से एनम के उद्देश्य से चूक गया है। कारण के भाग के लिए प्रश्न के तहत मेरी टिप्पणी देखें।
बोहेमियन

1
@ बोहेमियन: मैं "ईर्ष्या के उद्देश्य" को याद नहीं करता था - मैं हर समय उनका उपयोग करता हूं। ऊपर अपनी टिप्पणी के लिए मेरी प्रतिक्रिया देखें।
कैसाब्लांका

1
Enum.valuesOf विधि एक ही वस्तु लौटाती है यदि दो बार कहा जाता है?
एमरे अक्तरुख

104
  1. सुरक्षा और मूल्य सुरक्षा लिखें।
  2. गारंटी सिंगलटन।
  3. परिभाषित करने और तरीकों को ओवरराइड करने की क्षमता।
  4. योग्यता के बिना switchस्टेटमेंट caseस्टेटमेंट में मूल्यों का उपयोग करने की क्षमता ।
  5. निर्मित मूल्यों के माध्यम से क्रमिकरण में ordinal().
  6. मूल्य से नाम से सीरियललाइज़ेशन, जो भविष्य में प्रूफिंग की एक डिग्री प्रदान करता है।
  7. EnumSetऔर EnumMapकक्षाएं।

19
यह सब कहने के बाद, हर बार जब मैंने एक Enum में कोड डाला तो मुझे इसका पछतावा हुआ।
लोर्ने

4
आपको इसका अफसोस क्यों हुआ? मैं कभी नहीं ... था
glglgl

2
@glglgl Becasue ने एप्लिकेशन-विशिष्ट कोड को एक ऐसे स्थान पर रखा जहां मुझे लगा कि यह वास्तव में नहीं था, यह वास्तव में केवल मूल्यों के एक सेट को परिभाषित कर रहा था। अगर मेरे पास यह फिर से करने के लिए था, तो मैंने इसे कई switchबयानों में से एक में शामिल किया होगा जो कि एक Enumबिल्कुल उपयोग करने के लिए मूल प्रेरणा थे ।
लोर्ने

72

किसी ने भी उन्हें इस्तेमाल करने की क्षमता का उल्लेख नहीं किया switch बयानों ; मैं इसे भी फेंक दूंगा।

यह बिना उपयोग किए instanceof, संभावित रूप से भ्रमित करने वाले ifदृश्यों, या गैर-स्ट्रिंग / इंट स्विचिंग मानों के बिना मनमाने ढंग से जटिल ईनामों को साफ तरीके से उपयोग करने की अनुमति देता है । विहित उदाहरण एक राज्य मशीन है।


वैसे भी, आपने किसी भी लाभ का उल्लेख नहीं किया था बनाम स्थिर क्षेत्रों से, आप स्थैतिक क्षेत्रों के साथ स्विच स्टेटमेंट में पर्याप्त प्रकार का उपयोग कर सकते हैं। वास्तविक फ़ंक्शंस या परफ़ॉर्मेंस अंतर की आवश्यकता है
पूर्णता Genaut

@ लाभ यह है कि enums में एक स्ट्रिंग की तुलना में अधिक कार्यक्षमता है या अंतर-प्रश्न मतभेदों के बारे में था, जो मैंने प्रदान किया था। ओपी पहले से ही जानता है कि एनम क्या हैं, और किसी ने स्विच स्टेटमेंट का उल्लेख नहीं किया था जब मैंने यह 4.5 साल पहले पोस्ट किया था, और कम से कम कुछ लोगों ने पाया कि यह नई जानकारी प्रदान करता है (_ (ツ) _ / ¯
डेव न्यूटन

44

प्राथमिक लाभ प्रकार की सुरक्षा है। स्थिरांक के एक सेट के साथ, एक ही आंतरिक प्रकार के किसी भी मूल्य का उपयोग किया जा सकता है, त्रुटियों का परिचय। एक enum के साथ केवल लागू मानों का उपयोग किया जा सकता है।

उदाहरण के लिए

public static final int SIZE_SMALL  = 1;
public static final int SIZE_MEDIUM = 2;
public static final int SIZE_LARGE  = 3;

public void setSize(int newSize) { ... }

obj.setSize(15); // Compiles but likely to fail later

बनाम

public enum Size { SMALL, MEDIUM, LARGE };

public void setSize(Size s) { ... }

obj.setSize( ? ); // Can't even express the above example with an enum

3
कक्षाएं भी सुरक्षित हैं ...: / (स्थिर क्षेत्र कंटेनर वर्ग के प्रकार के हैं)
h3xStream

आप अभी भी इसे एक अमान्य मान दे सकते हैं, लेकिन यह एक संकलित समय त्रुटि होगी जो स्पॉट करना बहुत आसान है।
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz

2
आप setSize(null)अपने दूसरे उदाहरण में कॉल कर सकते हैं , लेकिन यह पहले उदाहरण की त्रुटि की तुलना में बहुत जल्द विफल होने की संभावना है।
जेफरी

42

भ्रम की स्थिति कम होती है। Fontउदाहरण के लिए ले लो । इसमें एक कंस्ट्रक्टर है जो Fontआप चाहते हैं, उसके आकार और उसकी शैली ( new Font(String, int, int)) का नाम लेता है । आज तक मुझे याद नहीं है कि शैली या आकार पहले आता है या नहीं। अगर Fontएक का इस्तेमाल किया था enumइसके विभिन्न शैलियों के सभी के लिए ( PLAIN, BOLD, ITALIC, BOLD_ITALIC), इसके निर्माता की तरह लग रहे हैं Font(String, Style, int), किसी भी भ्रम को रोकने। दुर्भाग्यवश, enumजब Fontकक्षा बनाई गई थी, तब आसपास नहीं थे , और चूंकि जावा को रिवर्स संगतता बनाए रखना था, इसलिए हम हमेशा इस अस्पष्टता से ग्रस्त रहेंगे।

बेशक, यह स्थिरांक के enumबजाय उपयोग करने के लिए एक तर्क public static finalहै। एनम एकल और बाद के अनुकूलन (IE रणनीति पैटर्न ) के लिए अनुमति देते हुए डिफ़ॉल्ट व्यवहार को लागू करने के लिए भी परिपूर्ण हैं । उत्तरार्द्ध का एक उदाहरण है java.nio.files ' OpenOptionऔर StandardOpenOptionअगर एक डेवलपर अपने ही गैर मानक बनाना चाहता था: OpenOption, वह कर सकती थी।


आपका 'फॉण्ट' मामला अभी भी अस्पष्ट है अगर एक ही दुश्मनी के दो के लिए कहा गया था। उस समस्या का विहित जवाब जिसे कई भाषाएं नामांकित पैरामीटर कहते हैं । यह या बेहतर आईडीई विधि हस्ताक्षर का समर्थन है।
आआआआआआआआआआआआआआआ आआआआआआआआ आआआआआआआआआआआआआआआआआआआआआआ

1
@aaaaaa मैं कई मामलों में जहां एक निर्माता एक ही के दो ले जाएगा नहीं देखा है enumका उपयोग किए बिना varargs या Setउनमें से एक मनमाना संख्या लेने के लिए।
जेफरी

@aaaaaa नामित मापदंडों के साथ मुख्य मुद्दा यह कार्यान्वयन विवरण (पैरामीटर का नाम) पर निर्भर करता है। मैं एक इंटरफ़ेस बना सकता हूं interface Foo { public void bar(String baz); }। किसी एक वर्ग जो आह्वान करता है bar: someFoo.bar(baz = "hello");। मैं के हस्ताक्षर को बदलने Foo::barके लिए public void bar(String foobar)। अब जिस व्यक्ति ने फोन someFooकिया है, उसे अपने कोड को संशोधित करना होगा, यदि वे अभी भी इसे काम करना चाहते हैं।
जेफरी

मुझे याद नहीं है कि लगातार एनुम प्रकार या तो देखें, लेकिन सोचा कि एक सामान्य व्यक्ति DAY_OF_WEEK या कुछ इसी तरह का हो सकता है। और इंटरफ़ेस के बारे में अच्छी बात - ऐसा नहीं सोचा था। व्यक्तिगत रूप से मैं उस समस्या को बड़े पैमाने पर अस्पष्टता पर ले जाऊंगा, जो गैर-नामित मापदंडों के कारण होती है, जिसके लिए मजबूत आईडीई समर्थन की आवश्यकता होती है। मैं समझता हूं कि हालांकि यह एक निर्णय कॉल है, और एपीआई परिवर्तनों को तोड़ना गंभीरता से विचार करने के लिए कुछ है।
आउआ

26

यहाँ कई अच्छे उत्तर हैं, लेकिन कोई भी उल्लेख नहीं करता है कि संग्रह एपीआई क्लासेस / विशेष रूप से एनम के लिए अत्यधिक अनुकूलित कार्यान्वयन हैं :

ये एनुम विशिष्ट वर्ग केवल Enumउदाहरणों को स्वीकार करते हैं ( EnumMapकेवल Enumकुंजी के रूप में केवल स्वीकार करते हैं ), और जब भी संभव हो, वे अपने कार्यान्वयन में कॉम्पैक्ट प्रतिनिधित्व और बिट हेरफेर करने के लिए वापस आते हैं।

इसका क्या मतलब है?

यदि हमारे Enumप्रकार में अधिक नहीं है कि 64 तत्व (वास्तविक जीवन के अधिकांश Enumउदाहरण इसके लिए अर्हता प्राप्त करेंगे), तो कार्यान्वयन तत्वों को एक ही longमूल्य में संग्रहीत करते हैं , Enumप्रश्न में प्रत्येक उदाहरण इस 64-बिट लंबे समय के साथ जुड़ा होगा long। एक तत्व में जोड़ने के EnumSetलिए बस 1 को उचित बिट सेट कर रहा है, इसे हटा रहा है बस उस बिट को 0 पर सेट कर रहा है। यदि कोई तत्व Setसिर्फ एक बिटमेस्क टेस्ट है तो परीक्षण! अब आप Enumइस के लिए प्यार करना होगा !


1
मुझे इन दोनों के बारे में पहले से पता था, लेकिन मैंने अभी आपके What does this mean?अनुभाग से बहुत कुछ सीखा है । मुझे पता था कि आकार 64 में कार्यान्वयन में एक विभाजन था, लेकिन मैं वास्तव में नहीं जानता था कि क्यों
क्रिस्टोफर रुकिंस्की

15

उदाहरण:

public class CurrencyDenom {
   public static final int PENNY = 1;
 public static final int NICKLE = 5;
 public static final int DIME = 10;
public static final int QUARTER = 25;}

जावा कॉन्स्टेंट की सीमा

1) नो टाइप-सेफ्टी : सबसे पहले यह टाइप-सेफ नहीं है; आप उदाहरण के लिए 99 के लिए कोई वैध इंट वैल्यू असाइन कर सकते हैं, हालांकि उस मूल्य का प्रतिनिधित्व करने के लिए कोई सिक्का नहीं है।

2) कोई सार्थक मुद्रण नहीं : इनमें से किसी भी स्थिरांक का मुद्रण मूल्य सिक्के के सार्थक नाम के बजाय इसके संख्यात्मक मान को मुद्रित करेगा, जैसे कि जब आप NICKLE प्रिंट करेंगे तो यह "NICKLE" के बजाय "5" प्रिंट करेगा।

3) कोई नाम स्थान नहीं : मुद्राडेनोम स्थिरांक तक पहुँचने के लिए हमें वर्ग के नाम को उपसर्ग करने की आवश्यकता है जैसे कि CurrencyDenom।

एनम का लाभ

1) जावा में Enums प्रकार-सुरक्षित हैं और उनका स्वयं का नाम-स्थान है। इसका मतलब है कि आपकी ईमू में उदाहरण के लिए "नीचे" उदाहरण के लिए एक प्रकार होगा और आप एनम कॉन्स्टेंट में निर्दिष्ट के अलावा कोई भी मूल्य निर्दिष्ट नहीं कर सकते।

public enum Currency {PENNY, NICKLE, DIME, QUARTER};

Currency coin = Currency.PENNY; coin = 1; //compilation error

2) जावा में Enum क्लास या इंटरफ़ेस की तरह संदर्भ प्रकार हैं और आप जावा Enum के अंदर कंस्ट्रक्टर, विधियों और चर को परिभाषित कर सकते हैं जो इसे Enum की तुलना में C और C ++ में अधिक शक्तिशाली बनाता है जैसा कि जावा Enum प्रकार के अगले उदाहरण में दिखाया गया है।

3) आप निर्माण समय में एनम स्थिरांक के मूल्यों को निर्दिष्ट कर सकते हैं जैसा कि नीचे दिए गए उदाहरण में दिखाया गया है: सार्वजनिक एनम मुद्रा {पेनी (1), निकले (5), डीआईएमई (10), क्वार (25)}; लेकिन इसके लिए काम करने के लिए आपको एक सदस्य चर और एक कंस्ट्रक्टर को परिभाषित करने की आवश्यकता है क्योंकि PENNY (1) वास्तव में एक कंस्ट्रक्टर को बुला रहा है जो इंट वैल्यू को स्वीकार करता है, नीचे उदाहरण देखें।

public enum Currency {
    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);
    private int value;

    private Currency(int value) {
            this.value = value;
    }
}; 

संदर्भ: https://javarevisited.blogspot.com/2011/08/enum-in-java-example-tutorial.html


11

एनमों का पहला लाभ, जैसा कि आपने पहले ही देखा है, वाक्यविन्यास सरलता है। लेकिन एनमों का मुख्य बिंदु स्थिरांक का एक प्रसिद्ध सेट प्रदान करना है, जो डिफ़ॉल्ट रूप से, एक सीमा बनाता है और प्रकार और मूल्य सुरक्षा जांच के माध्यम से अधिक व्यापक कोड विश्लेषण करने में मदद करता है।

एनम की वे विशेषताएँ प्रोग्रामर और कंपाइलर दोनों की मदद करती हैं। उदाहरण के लिए, मान लें कि आप एक फ़ंक्शन देखते हैं जो पूर्णांक को स्वीकार करता है। उस पूर्णांक का क्या अर्थ हो सकता है? आप किस तरह के मूल्यों में पास हो सकते हैं? आप वास्तव में अभी नहीं जानते हैं। लेकिन अगर आप एक ऐसा कार्य देखते हैं, जो एनम को स्वीकार करता है, तो आप बहुत अच्छी तरह से सभी संभावित मूल्यों को जानते हैं जो आप में पारित कर सकते हैं।

कंपाइलर के लिए, एनमेस मानों की एक सीमा निर्धारित करने में मदद करते हैं और जब तक आप एनम सदस्यों को विशेष मान नहीं देते हैं, वे 0 और ऊपर से अच्छी तरह से होते हैं। यह कोड में त्रुटियों को स्वचालित रूप से टाइप सुरक्षा जांच और अधिक के माध्यम से ट्रैक करने में मदद करता है। उदाहरण के लिए, कंपाइलर आपको चेतावनी दे सकता है कि आप अपने स्विच स्टेटमेंट (यानी जब आपके पास न हों) में सभी संभव एनुम मानों को न संभालेंdefault केस और एन एनम वैल्यूज़ में से केवल एक ही हैंडल करें)। यह तब भी आपको चेतावनी देता है जब आप एक मनमाने ढंग से पूर्णांक को एनम में बदलते हैं क्योंकि एनम की मानों की सीमा पूर्णांक से कम होती है और इससे फ़ंक्शन में त्रुटियों को ट्रिगर किया जा सकता है जो वास्तव में पूर्णांक को स्वीकार नहीं करता है। इसके अलावा, मान के 0 और ऊपर से स्विच के लिए जंप टेबल बनाना आसान हो जाता है।

यह न केवल जावा के लिए, बल्कि अन्य भाषाओं के लिए भी एक सख्त प्रकार की जाँच के साथ सच है। C, C ++, D, C # अच्छे उदाहरण हैं।


4

एक एनम एक निजी कंस्ट्रक्टर्स के साथ निहित है, इसके सभी मान एक ही प्रकार या एक उप-प्रकार के हैं, आप इसका उपयोग करके अपने सभी मूल्यों को प्राप्त कर सकते हैं values(), इसके name()या ordinal()मूल्य प्राप्त कर सकते हैं या आप संख्या या नाम से एनम को देख सकते हैं।

आप उपवर्गों को भी परिभाषित कर सकते हैं (भले ही विशेष रूप से अंतिम रूप से, कुछ आप किसी अन्य तरीके से नहीं कर सकते हैं)

enum Runner implements Runnable {
    HI {
       public void run() {
           System.out.println("Hello");
       }
    }, BYE {
       public void run() {
           System.out.println("Sayonara");
       }
       public String toString() {
           return "good-bye";
       }
    }
 }

 class MYRunner extends Runner // won't compile.

4

एनम लाभ:

  1. एनम टाइप-सेफ़ हैं, स्टैटिक फील्ड नहीं हैं
  2. मूल्यों की एक सीमित संख्या है (गैर-मौजूदा एनम मान को पारित करना संभव नहीं है। यदि आपके पास स्थिर वर्ग फ़ील्ड हैं, तो आप वह गलती कर सकते हैं)
  3. प्रत्येक एनम में कई गुण (फ़ील्ड / गेटर्स) असाइन किए गए - इनकैप्सुलेशन हो सकते हैं। इसके अलावा कुछ सरल तरीके: YEAR.toSeconds () या समान। तुलना करें: Colors.RED.getHex () Colors.toHex (Colors.RED) के साथ

"जैसे कि एनम तत्व को आसानी से एक निश्चित मान प्रदान करने की क्षमता"

enum EnumX{
  VAL_1(1),
  VAL_200(200);
  public final int certainValue;
  private X(int certainValue){this.certainValue = certainValue;}
}

"और फलस्वरूप प्रयास की एक सभ्य राशि के बिना एक एनम के लिए एक पूर्णांक में परिवर्तित करने की क्षमता" एनाम जो करने के लिए int परिवर्तित करने के लिए एक विधि जोड़ें। बस स्थैतिक HashMap <Integer, EnumX> मानचित्रण जावा Enum युक्त जोड़ें ।

यदि आप वास्तव में ord = VAL_200.ordinal () को वापस val_200 में परिवर्तित करना चाहते हैं तो उपयोग करें: EnumX.values ​​() [ord]


3

एक और महत्वपूर्ण अंतर यह है कि जावा कंपाइलर आदिम प्रकार केstatic final क्षेत्रों और स्ट्रिंग को शाब्दिक के रूप में मानता है। इसका मतलब है कि ये स्थिरांक इनलाइन हो गए हैं। यह प्रीप्रोसेसर के समान है । इस SO प्रश्न को देखें । एनम के साथ ऐसा नहीं है।C/C++ #define



2

सबसे बड़ा फायदा है एनम सिंगलेट्स को लिखना आसान है और थ्रेड-सेफ:

public enum EasySingleton{
    INSTANCE;
}

तथा

/**
* Singleton pattern example with Double checked Locking
*/
public class DoubleCheckedLockingSingleton{
     private volatile DoubleCheckedLockingSingleton INSTANCE;

     private DoubleCheckedLockingSingleton(){}

     public DoubleCheckedLockingSingleton getInstance(){
         if(INSTANCE == null){
            synchronized(DoubleCheckedLockingSingleton.class){
                //double checking Singleton instance
                if(INSTANCE == null){
                    INSTANCE = new DoubleCheckedLockingSingleton();
                }
            }
         }
         return INSTANCE;
     }
}

दोनों समान हैं और इसने कार्यान्वयन द्वारा स्वयं के द्वारा सीरियलाइज़ेशन को संभाला

//readResolve to prevent another instance of Singleton
    private Object readResolve(){
        return INSTANCE;
    }

अधिक


0

मुझे लगता है कि enumनहीं हो सकता final, क्योंकि हुड कंपाइलर के तहत प्रत्येक enumप्रविष्टि के लिए उप-वर्ग उत्पन्न करता है ।

अधिक जानकारी स्रोत से


आंतरिक रूप से, वे अंतिम नहीं हैं, क्योंकि - जैसा कि आप कहते हैं - आंतरिक रूप से उपवर्ग हो सकता है। लेकिन अफसोस, आप उन्हें अपने दम पर नहीं तोड़ सकते, उदाहरण के लिए इसे अपने मूल्यों के साथ बढ़ा सकते हैं।
11

0

यहाँ पर पोस्ट की गई एनम के कई फायदे हैं, और मैं अभी इस तरह के एनम बना रहा हूँ जैसे कि प्रश्न में पूछा गया है। लेकिन मेरे पास 5-6 क्षेत्रों के साथ एक एनम है।

enum Planet{
EARTH(1000000, 312312321,31232131, "some text", "", 12),
....
other planets
....

इस प्रकार के मामलों में, जब आपके पास कई क्षेत्र होते हैं, तो यह समझना बहुत मुश्किल होता है कि कौन सा क्षेत्र किस क्षेत्र से संबंधित है, क्योंकि आपको कंस्ट्रक्टर और आई-बॉल देखने की आवश्यकता है।

ऐसी वस्तुओं को बनाने के लिए static finalस्थिरांक के साथ वर्ग और Builderपैटर्न का उपयोग करना इसे और अधिक पठनीय बनाता है। लेकिन, अगर आपको उनकी आवश्यकता है, तो आपको एनम का उपयोग करने के अन्य सभी फायदे खो देंगे। ऐसी कक्षाओं का एक नुकसान यह है, आपको Planetवस्तुओं को मैन्युअल रूप से जोड़ने की आवश्यकता list/setहैPlanets.

मैं अभी भी इस तरह के वर्ग से अधिक enum पसंद करते हैं के रूप में values()काम में आता है और आप उन्हें में उपयोग करने की आवश्यकता है, तो आप कभी पता नहीं switchया EnumSetया EnumMapभविष्य में :)


0

मुख्य कारण: Enums आपको अच्छी तरह से संरचित कोड लिखने में मदद करते हैं जहां मापदंडों का अर्थ अर्थ स्पष्ट और दृढ़ता से-संकलन समय पर टाइप किया जाता है - सभी कारणों से अन्य उत्तर दिए गए हैं।

क्विड प्रो क्वो: जावा में बॉक्स के बाहर, सदस्यों का एक Enum सरणी अंतिम है। यह सामान्य रूप से अच्छा है क्योंकि यह मूल्य सुरक्षा और परीक्षण में मदद करता है, लेकिन कुछ स्थितियों में यह एक खामी हो सकती है, उदाहरण के लिए यदि आप किसी पुस्तकालय से मौजूदा आधार कोड का विस्तार कर रहे हैं। इसके विपरीत, यदि एक ही डेटा स्थिर फ़ील्ड के साथ एक वर्ग में है, तो आप रनटाइम के समय आसानी से उस वर्ग के नए उदाहरण जोड़ सकते हैं (आपको उस वर्ग के लिए किसी भी Iterable में इन्हें जोड़ने के लिए कोड लिखने की आवश्यकता हो सकती है)। लेकिन एनम के इस व्यवहार को बदला जा सकता है: प्रतिबिंब का उपयोग करके आप रनटाइम में नए सदस्यों को जोड़ सकते हैं या मौजूदा सदस्यों को बदल सकते हैं, हालांकि यह संभवतः केवल उन विशेष स्थितियों में किया जाना चाहिए जहां कोई विकल्प नहीं है: यानी यह एक हैकी समाधान है और अप्रत्याशित मुद्दों का उत्पादन कर सकता है, मेरा जवाब देखिएक्या मैं जावा में रनटाइम पर गणना के तत्वों को जोड़ और हटा सकता हूं

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.