2010-10-25 16 views
26

मैं गतिशील enum लुकअप से संबंधित एक संकलन त्रुटि ("बाउंड मिस्चैच: ...") के आसपास पाने की कोशिश कर रहा हूं।Enum.valueOf (कक्षा <T> enumType, स्ट्रिंग नाम) प्रश्न

String enumName = whatever.getEnumName(); 
Class<? extends Enum<?>> enumClass = whatever.getEnumClass(); 
Enum<?> enumValue = Enum.valueOf(enumClass, enumName); 

जो कुछ भी मैं करता हूँ, मैं हमेशा उस संकलन त्रुटि के साथ समाप्त:

असल में मैं कुछ इस तरह हासिल करना चाहते हैं। ईमानदारी से, जेनेरिक और enums मेरे लिए काफी दिमाग में हैं ...

मैं यहाँ क्या गलत कर रहा हूँ?

उत्तर

22

मुझे लगता है कि यह ठीक उसी तरह काम नहीं करेगा जब तक कि आपके पास एक प्रकार चर (किसी प्रकार या विधि हस्ताक्षर के माध्यम से) तक पहुंच न हो।

public static <T extends Enum<T>> T valueOf(
    Class<T> enumType, 
    String name 
); 

एक प्रकार चर के बिना एक टी पाने के लिए कोई तरीका नहीं है: समस्या Enum.valueOf की विधि हस्ताक्षर है। लेकिन आप इसे इस तरह से कर सकते हैं अगर आप कुछ संकलक चेतावनी को दबाने के लिए तैयार हैं:

public enum King{ 
    ELVIS 
} 

@SuppressWarnings({ "unchecked", "rawtypes" }) 
public static void main(final String[] args){ 
    final Class<? extends Enum> enumType = King.class; 
    final Enum<?> theOneAndOnly = Enum.valueOf(enumType, "ELVIS"); 
    System.out.println(theOneAndOnly.name()); 
} 

आउटपुट:

एल्विस

+0

सवाल enums, जेनरिक और प्रतिबिंब के बारे में है। आप जेनरिक ध्यान नहीं देते हैं , बिंदु क्या है? विशेष रूप से 'दुर्लभ प्रकार' जैसे 'कक्षा <' के लिए जा रहा है? एनम> ' –

+2

बिंदु यह है कि ए) यह अन्यथा सहायक विधि या प्रकार के बिना काम नहीं कर सकता है और बी) हम निश्चित रूप से जानते हैं कि कोई भी 'कक्षा 'कक्षा <ई को भी संतुष्ट करेगा' ई > '(क्योंकि एनम क्लास काम करने का तरीका है) भले ही किसी प्रकार के चर के बिना जांचने का कोई तरीका न हो। '@ SuppressWarnings' एक एनोटेशन है जिसे आपको केवल तभी उपयोग करना चाहिए यदि आप जानते हैं कि आप क्या कर रहे हैं, और मुझे पता है। –

19

समस्या Class<? extends Enum<?>> के साथ है। हम E extends Enum<E> चाहते हैं, लेकिन हम इसे प्राप्त नहीं कर सकते क्योंकि हमारे पास दो अलग वाइल्डकार्ड हैं।

तो हम एक सामान्य पैरामीटर, संभव एक विधि को फोन करके शुरू की शुरू करने की जरूरत है:

enum MyEnum { 
    ME; 
} 

public class EnName { 
    public static void main(String[] args) { 
     Enum<?> value = of(MyEnum.class, "ME"); 
     System.err.println(value); 
    } 
    private static <E extends Enum<E>> E of(Class<E> clazz, String name) { 
     E value = Enum.valueOf(clazz, name); 
     return value; 
    } 
} 

लेकिन प्रतिबिंब खाद और बहुत मुश्किल से ही तुम क्या चाहते है। ऐसा मत करो

+1

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

6

वास्तव में एक वैकल्पिक दृष्टिकोण है: आप Class.getEnumConstants का उपयोग कर सकते हैं और Enum.valueOf का अपना कार्यान्वयन रोल कर सकते हैं जिसमें एक ही प्रकार की समस्या नहीं है। नकारात्मकता यह है कि आप एक सामान्य Enum<?> वापस प्राप्त करते हैं - लेकिन अगर आपको पता था कि आप किस प्रकार से आ रहे थे, तो आप Enum.valueOf का उपयोग करने में सक्षम होंगे।

private static Enum<?> findEnumValue(Class<? extends Enum<?>> enumType, String value) { 
    return Arrays.stream(enumType.getEnumConstants()) 
       .filter(e -> e.name().equals(value)) 
       .findFirst() 
       .orElse(null); 
} 

(ध्यान दें कि मेरी संस्करण रिटर्न null हो, तो बल्कि एक IllegalArgumentException फेंकने की तुलना में इस तरह का कोई निरंतर है, लेकिन यह बदलने के लिए एक छोटी सी बात है।

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