2009-11-09 22 views
19

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

Field f = getTheField(); // Dummy method that returns my Field 
Class<?> c = f.getType(); 
if (c == int.class) { 
    c = Integer.class; 
} 
else if (c == float.class) { 
    c = Float.class; 
} 
// etc 
myMethod(c); 

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

उत्तर

33

मैं अपने उत्तर में Google संग्रह लाइब्रेरी का उपयोग करता हूं, क्योंकि मैं उस तरह खराब हूं, लेकिन आप शायद यह देख सकते हैं कि सादा हैशमैप्स के साथ इसे कैसे करना है।

// safe because both Long.class and long.class are of type Class<Long> 
    @SuppressWarnings("unchecked") 
    private static <T> Class<T> wrap(Class<T> c) { 
    return c.isPrimitive() ? (Class<T>) PRIMITIVES_TO_WRAPPERS.get(c) : c; 
    } 

    private static final Map<Class<?>, Class<?>> PRIMITIVES_TO_WRAPPERS 
    = new ImmutableMap.Builder<Class<?>, Class<?>>() 
     .put(boolean.class, Boolean.class) 
     .put(byte.class, Byte.class) 
     .put(char.class, Character.class) 
     .put(double.class, Double.class) 
     .put(float.class, Float.class) 
     .put(int.class, Integer.class) 
     .put(long.class, Long.class) 
     .put(short.class, Short.class) 
     .put(void.class, Void.class) 
     .build(); 

ऐसा नहीं है कि कुछ भी नहीं है इस के लिए JDK में मौजूद है, लेकिन वास्तव में कुछ नहीं करता है अजीब है।

संपादित करें: मैं पूरी तरह से भूल गया था कि हम इस जारी किया:

http://google.github.io/guava/releases/21.0/api/docs/com/google/common/primitives/Primitives.html

यह चादर() विधि, प्लस खोलना() और कुछ अन्य आनुषंगिक बातों है।

+0

तो मूल रूप से एक ही बात ... :) उत्तर के लिए धन्यवाद। असल में इस समय कोई दूसरा रास्ता नहीं है। –

6

आप कक्षा.इस प्राइमेटिव() को यह जान सकते हैं कि यह एक आदिम है या नहीं, हालांकि, जेडीके के भीतर कक्षाओं को बदलने के लिए कोई मुक्केबाजी विधि नहीं है। इससे संबंधित कम से कम एक open bug है।

+0

रैपर कक्षाओं में भी फ़ील्ड हैं जो आपको आदिम कक्षाओं (उदाहरण के लिए, 'डबल। वाईपीईई' 'double.class' के समान), लेकिन प्रोग्रामेटिक रूप से लाभ लेने के लिए कोई गैर-बदसूरत तरीका नहीं है। –

33

Apache Commons Lang में ऐसा करने के लिए उपयोगिता विधि है (ClassUtils.primitiveToWrapper()), जो कि कवर के नीचे बदसूरत होगी, लेकिन कम से कम आप इसे अच्छा दिखा सकते हैं।

Class<?> primitive=long.class; 
    Class<?> boxed=Array.get(Array.newInstance(primitive,1),0).getClass(); 
    System.out.println(primitive.getName()); 
    System.out.println(boxed.getName()); 
5

यहाँ एक और तरीका अगर आप अत्यधिक अनुकूलित कोड की आवश्यकता नहीं है। लेकिन निश्चित रूप से "com.sun" पैकेज से कक्षाओं का उपयोग करने की वास्तव में अनुशंसा नहीं की जाती है ...

0

भी com.sun.beans.finder.PrimitiveWrapperMap # GetType (primitiveName) नहीं है:

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