2010-10-06 14 views
8

मैं प्रलेखन और स्रोत कोड को देख रहा था, क्योंकि मैं निश्चित होना चाहता था कि मान() हमेशा उस क्रम में एक सरणी वापस कर देगा जिसमें एनम मान घोषित किए गए हैं। बाहर निकलता है, यह in the documentation है जहां तक ​​मैं कह सकता हूं।कहां से आता है Enum.values ​​()?

मैंने एनम कक्षा के लिए स्रोत कोड की जांच की, और कोई भाग्य नहीं (there is a related, private "getValues" method)।

तो मेरा अनुमान है कि यह है कि कुछ संकलक/दुभाषिया-foo पहले से ही एक वर्ग है कि Enum की तरह एक घोषणा से बाहर फैली हुई है बनाने के लिए चल रहा है:

public static enum MyEnum 

तो मानों() भी स्थिर एक में अनुवाद किया है संकलन के दौरान हार्डकोडेड सरणी? या यह वास्तव में रनटाइम पर एक विधि है, और यदि हां, तो यह कहां परिभाषित किया गया है?

+0

यदि आप बहुत अधिक परवाह करते हैं, तो शायद इसका मतलब है कि अगर आपके एनम घोषणा में आप सामान लेते हैं तो कुछ तोड़ देगा। यह वास्तव में नाजुक है। तो मैं कहूंगा कि अगर आप परवाह है, तो शायद आपके पास एक अजीब डिजाइन है। यह आपके लिए क्यों मायने रखता है कि वे क्रम में हैं? –

+0

+1 सिर्फ शीर्षक के लिए। – Zoe

+0

@ मार्क पीटर्स - क्योंकि मैं कई स्थानों पर आदेशित मेनू आइटम के लिए enums का उपयोग कर रहा हूँ। निश्चित रूप से, मैं कुछ प्रकार के ऑर्डरिंग फ़ंक्शन बना सकता हूं जो उन्हें कुछ क्रम में वापस कर देता है ... लेकिन क्यों? यदि मैं उन्हें स्थानांतरित करता हूं तो यह तोड़ नहीं जाएगा, यह केवल ऐप में प्रस्तुत किए गए क्रम को बदल देगा। – DougW

उत्तर

13

values() विधि enum प्रकार की परिभाषा का हिस्सा है। Enum बेस क्लास के साथ भ्रमित नहीं होना चाहिए। औपचारिक परिभाषा Section 8.9 of the JLS में है जो आदेश देता है कि ऑर्डर लौटाया गया क्रम क्रम से मेल खाता है।

+0

+1! –

+0

बिल्कुल सही, यही वह है जो मैंने माना था। धन्यवाद! – DougW

1

आपके द्वारा प्रदान किया गया लिंक (जहां एक निजी getValues विधि है) Apache Harmony (संस्करण 6, जो एक खुला स्रोत जावा एसई है) से है। उनके पास ओरेकल के Enum वर्ग (जिसमें कोई निजी getValues विधि नहीं है) के लिए एक अलग कार्यान्वयन है।

ओरेकल जावा (लेखन के समय संस्करण 1.6.0-21) valueOf(Class<T> enumType, String name) है। यहाँ इसके कार्यान्वयन है:

/** 
    * Returns the enum constant of the specified enum type with the 
    * specified name. The name must match exactly an identifier used 
    * to declare an enum constant in this type. (Extraneous whitespace 
    * characters are not permitted.) 
    * 
    * @param enumType the <tt>Class</tt> object of the enum type from which 
    *  to return a constant 
    * @param name the name of the constant to return 
    * @return the enum constant of the specified enum type with the 
    *  specified name 
    * @throws IllegalArgumentException if the specified enum type has 
    *   no constant with the specified name, or the specified 
    *   class object does not represent an enum type 
    * @throws NullPointerException if <tt>enumType</tt> or <tt>name</tt> 
    *   is null 
    * @since 1.5 
    */ 
    public static <T extends Enum<T>> T valueOf(Class<T> enumType, 
               String name) { 
     T result = enumType.enumConstantDirectory().get(name); 
     if (result != null) 
      return result; 
     if (name == null) 
      throw new NullPointerException("Name is null"); 
     throw new IllegalArgumentException(
      "No enum const " + enumType +"." + name); 
    } 

संक्षेप में, यह कैसे अपाचे उनके valueOf कि अलग है कार्यान्वित है।


Enum (या enum) एक सार्वजनिक स्थैतिक विधि values() कि enumerated मान स्थिरांक enum अंदर घोषित रिटर्न कहा जाता है। यह संकलक द्वारा आबादी है।

+2

* कंपकंपी * मैं अभी भी "ओरेकल की एनम क्लास" या "द ओरेकल जावा" देखकर बाहर निकल गया हूं। मुझे लगता है कि आप ओरेकल डेटाबेस में उपयोग के लिए किए गए जेवीएम के बारे में बात कर रहे हैं। –

+0

नाम बदलने पर रोकें जब तक ओरेकल ने वास्तव में जावा के लिए कुछ प्रमुख नहीं किया है। – irreputable

+0

एलओएल .... यदि आपने लोगों को नहीं देखा है, तो अधिकांश 'sun.com' साइटें अब 'oracle.com' हैं। साथ ही साथ अपनाना भी हो सकता है .... –

2

जैसा कि आप एक enum disassemlbing द्वारा प्राप्त बाइटकोड से देख सकते हैं, values() enums पर विधि बस private static सरणी की एक प्रति वापस लौटाती है जिसमें सभी घोषित एनम स्थिर होते हैं। यह सरणी ENUM$VALUES एक स्थिर initilization ब्लॉक में भर गया है।

DaysOfTheWeek.java

public enum DaysOfTheWeek { 
    MONDAY, 
    TUESDAY, 
    WEDNESDAY, 
    THURSDAY, 
    FRIDAY, 
    SATURDAY, 
    SUNDAY 
} 

DaysOfTheWeek.java disassembled

स्थिर ब्लॉक के बाद, बाईटकोड चिह्नित 0-92 initializes enum स्थिरांक, बाईटकोड चिह्नित 94-139 उन डालता है एक सरणी में स्थिरांक और 140 चिह्नित बाइटकोड वर्ग के ENUM$VALUES स्थिर क्षेत्र में सरणी निर्दिष्ट करता है। values() विधि में कोड फ़ील्ड पर System.arraycopy पर कॉल करके केवल सरणी की प्रतिलिपि बनाता है और प्रतिलिपि देता है।

Compiled from "DaysOfTheWeek.java" 
public final class DaysOfTheWeek extends java.lang.Enum{ 
public static final DaysOfTheWeek MONDAY; 

public static final DaysOfTheWeek TUESDAY; 

public static final DaysOfTheWeek WEDNESDAY; 

public static final DaysOfTheWeek THURSDAY; 

public static final DaysOfTheWeek FRIDAY; 

public static final DaysOfTheWeek SATURDAY; 

public static final DaysOfTheWeek SUNDAY; 

static {}; 
    Code: 
    0: new #1; //class DaysOfTheWeek 
    3: dup 
    4: ldC#18; //String MONDAY 
    6: iconst_0 
    7: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    10: putstatic #23; //Field MONDAY:LDaysOfTheWeek; 
    13: new #1; //class DaysOfTheWeek 
    16: dup 
    17: ldC#25; //String TUESDAY 
    19: iconst_1 
    20: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    23: putstatic #26; //Field TUESDAY:LDaysOfTheWeek; 
    26: new #1; //class DaysOfTheWeek 
    29: dup 
    30: ldC#28; //String WEDNESDAY 
    32: iconst_2 
    33: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    36: putstatic #29; //Field WEDNESDAY:LDaysOfTheWeek; 
    39: new #1; //class DaysOfTheWeek 
    42: dup 
    43: ldC#31; //String THURSDAY 
    45: iconst_3 
    46: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    49: putstatic #32; //Field THURSDAY:LDaysOfTheWeek; 
    52: new #1; //class DaysOfTheWeek 
    55: dup 
    56: ldC#34; //String FRIDAY 
    58: iconst_4 
    59: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    62: putstatic #35; //Field FRIDAY:LDaysOfTheWeek; 
    65: new #1; //class DaysOfTheWeek 
    68: dup 
    69: ldC#37; //String SATURDAY 
    71: iconst_5 
    72: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    75: putstatic #38; //Field SATURDAY:LDaysOfTheWeek; 
    78: new #1; //class DaysOfTheWeek 
    81: dup 
    82: ldC#40; //String SUNDAY 
    84: bipush 6 
    86: invokespecial #19; //Method "<init>":(Ljava/lang/String;I)V 
    89: putstatic #41; //Field SUNDAY:LDaysOfTheWeek; 
    92: bipush 7 
    94: anewarray #1; //class DaysOfTheWeek 
    97: dup 
    98: iconst_0 
    99: getstatic #23; //Field MONDAY:LDaysOfTheWeek; 
    102: aastore 
    103: dup 
    104: iconst_1 
    105: getstatic #26; //Field TUESDAY:LDaysOfTheWeek; 
    108: aastore 
    109: dup 
    110: iconst_2 
    111: getstatic #29; //Field WEDNESDAY:LDaysOfTheWeek; 
    114: aastore 
    115: dup 
    116: iconst_3 
    117: getstatic #32; //Field THURSDAY:LDaysOfTheWeek; 
    120: aastore 
    121: dup 
    122: iconst_4 
    123: getstatic #35; //Field FRIDAY:LDaysOfTheWeek; 
    126: aastore 
    127: dup 
    128: iconst_5 
    129: getstatic #38; //Field SATURDAY:LDaysOfTheWeek; 
    132: aastore 
    133: dup 
    134: bipush 6 
    136: getstatic #41; //Field SUNDAY:LDaysOfTheWeek; 
    139: aastore 
    140: putstatic #43; //Field ENUM$VALUES:[LDaysOfTheWeek; 
    143: return 

public static DaysOfTheWeek[] values(); 
    Code: 
    0: getstatic #43; //Field ENUM$VALUES:[LDaysOfTheWeek; 
    3: dup 
    4: astore_0 
    5: iconst_0 
    6: aload_0 
    7: arraylength 
    8: dup 
    9: istore_1 
    10: anewarray #1; //class DaysOfTheWeek 
    13: dup 
    14: astore_2 
    15: iconst_0 
    16: iload_1 
    17: invokestatic #51; //Method java/lang/System.arraycopy:(Ljava/lang/Object;ILjava/lang/Object;II)V 
    20: aload_2 
    21: areturn 

public static DaysOfTheWeek valueOf(java.lang.String); 
    Code: 
    0: ldC#1; //class DaysOfTheWeek 
    2: aload_0 
    3: invokestatic #59; //Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum; 
    6: checkcast #1; //class DaysOfTheWeek 
    9: areturn 

} 
+0

+1 इसे कठिन तरीके से साबित करने के लिए;)। धन्यवाद। Spec के लिए – DougW

1

मैं डेवन के उत्तर में जोड़ दूंगा, values() विधि संकलक द्वारा संकलक द्वारा जोड़ा गया है।
enums tutorial से:

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

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