2008-10-07 20 views
44

मैं जावा में कुछ चिंतनशील विधि कॉल करने के लिए की जरूरत का प्रतिनिधित्व करता है लगता है। उन कॉलों में वे विधियां शामिल होंगी जिनमें तर्क हैं जो आदिम प्रकार (int, double, आदि) हैं। इस विधि को प्रतिबिंबित करने के तरीके को प्रतिबिंबित करने का तरीका int.class, double.class, आदि हैगतिशील रूप से वर्ग है कि एक आदिम जावा प्रकार

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

doSomething int double 
doSomethingElse java.lang.String boolean 

इनपुट java.lang.String की तरह कुछ था, तो मुझे लगता है मैं वापस कि कक्षा उदाहरण के लिए Class.forName("java.lang.String") इस्तेमाल कर सकते हैं पता है। आदिम प्रकार कक्षाओं को वापस पाने के लिए, उस विधि या किसी अन्य का उपयोग करने का कोई तरीका है?

संपादित करें: सभी उत्तरदाताओं के लिए धन्यवाद। यह स्पष्ट लगता है कि वहाँ कोई अंतर्निहित तरीका सफाई से मैं क्या चाहता हूं, तो मैं स्प्रिंग ढांचे से ClassUtils वर्ग पुन: उपयोग के लिए समझौता होगा। ऐसा लगता है कि Class.forName() के लिए एक प्रतिस्थापन शामिल है जो मेरी आवश्यकताओं के साथ काम करेगा। आदिम प्रकार के लिए

उत्तर

18

स्प्रिंग ढांचे एक उपयोगिता वर्ग ClassUtils जो स्थिर विधि forName शामिल हैं। इस विधि का उपयोग आपके द्वारा वर्णित सटीक उद्देश्य के लिए किया जा सकता है।

यदि आप वसंत पर निर्भरता नहीं चाहते हैं: source code of the method ई पाया जा सकता है। जी। here उनके सार्वजनिक भंडार पर। कक्षा स्रोत कोड अपाचे 2.0 मॉडल के तहत लाइसेंस प्राप्त है।

नोट हालांकि कि एल्गोरिदम प्राचीन प्रकार के हार्ड-कोड किए गए मानचित्र का उपयोग करता है।


संपादित करें: टिप्पणीकर्ताओं डेविड होर्वथ और पैट्रिक टूटा हुआ लिंक ओर इशारा करते हुए के लिए करने के लिए धन्यवाद।

+4

क्लासयूटिल.जावा फ़ाइल का स्रोत उस लिंक पर टूटा हुआ प्रतीत होता है। [यह एक, ऊपर लग रहा है मेरे लिए] (http://www.jarvana.com/jarvana/view/org/springframework/spring-core/3.1.0.RELEASE/spring-core-3.1.0.RELEASE-sources। जार /org/springframework/util/ClassUtils.java प्रारूप = ठीक) – Patrick

+1

@Patrick:? खेद है, आपकी लिंक भी टूट बन गया। हालांकि, स्प्रिंग ढांचा अब गिटहब पर उपलब्ध है। https://github.com/spring-projects/spring-framework/blob/master/spring-core/src/main/java/org/springframework/util/ClassUtils.java –

23

Class उदाहरणों प्राप्य हैं के रूप में आप जैसे का उपयोग कर कहा int.class, लेकिन यह भी संभव Integer.TYPE की तरह कुछ का उपयोग कर एक ही मूल्यों को प्राप्त करने के लिए है। प्रत्येक आदिम आवरण वर्ग एक स्थिर क्षेत्र, TYPE है, जो इसी आदिम वर्ग उदाहरण है शामिल हैं।

आप forName के माध्यम से आदिम वर्ग प्राप्त नहीं कर सकता है, लेकिन आप एक वर्ग है जो आसानी से उपलब्ध है से प्राप्त कर सकते हैं। यदि आप पूरी तरह प्रतिबिंब का उपयोग करना चाहिए, तो आप कुछ इस तरह की कोशिश कर सकते हैं:

Class clazz = Class.forName("java.lang.Integer"); 
Class intClass = clazz.getField("TYPE").get(null); 

intClass.equals(int.class);   // => true 
+0

यह सच है, और मैं इसके बारे में पता नहीं था। हालांकि, मेरी स्थिति में, मुझे किसी विधि को निर्दिष्ट करने का एक तरीका चाहिए जो प्रतिबिंबित रूप से कहा जा सकता है। इसलिए, यदि मैं int मानों का प्रतिनिधित्व करने के लिए java.lang.Integer स्वीकार करता हूं, तो मैं उन तरीकों को कॉल करने की क्षमता खो दूंगा जो पूर्णांक मान स्वीकार करते हैं। –

+0

आप यह देखने के लिए जांच सकते हैं कि क्या आपको कुछ मनमाने ढंग से विशेष प्रकार प्राप्त हुआ है (कहें: "int") और फिर उचित रूप से फिर से लिखें। कोई स्ट्रिंग मान नहीं है जिसे आप नाम के लिए फ़ीड कर सकते हैं जो एक प्राचीन प्रकार की कक्षा को पुनर्प्राप्त करेगा। –

+0

ठीक है, धन्यवाद। आपका जवाब सहायक था। –

16

शायद तुम सिर्फ पुरातन मैप करने की आवश्यकता और वर्गों के आराम के लिए "forName" विधि प्रदर्शन: मैं की तरह कुछ करना होगा

:

void someWhere(){ 
    String methodDescription = "doSomething int double java.lang.Integer java.lang.String" 
    String [] parts = methodDescription.split(); 
    String methodName= parts[0] 
    Class [] paramsTypes = getParamTypes(parts); // Well, not all the array, but a, sub array from 1 to arr.length.. 

    Method m = someObject.class.getMethod(methodName, paramTypes); 
    etc. etc etc. 
} 

public Class[] paramTypes(String [] array){ 
    List<Class> list = new ArrayList<Class>(); 
    for(String type : array) { 
     if(builtInMap.contains(type)) { 
      list.add(builtInMap.get(type)); 
      }else{ 
      list.add(Class.forName(type)); 
      } 
    } 
    return list.toArray(); 
} 

    // That's right. 
Map<String,Class> builtInMap = new HashMap<String,Class>();{ 
     builtInMap.put("int", Integer.TYPE); 
     builtInMap.put("long", Long.TYPE); 
     builtInMap.put("double", Double.TYPE); 
     builtInMap.put("float", Float.TYPE); 
     builtInMap.put("bool", Boolean.TYPE); 
     builtInMap.put("char", Character.TYPE); 
     builtInMap.put("byte", Byte.TYPE); 
     builtInMap.put("void", Void.TYPE); 
     builtInMap.put("short", Short.TYPE); 
} 

है यही कारण है कि, एक नक्शा जहां बनाने प्राइमेटिव प्रकारों को संग्रहीत किया जाता है और यदि विवरण एक आदिम से संबंधित है तो मैप किए गए वर्ग का उपयोग करें। लचीलापन जोड़ने के लिए यह मानचित्र बाहरी कॉन्फ़िगरेशन फ़ाइल से भी लोड किया जा सकता है ताकि आप java.lang.String के बजाय स्ट्रिंग को अंतर्निहित रूप में जोड़ सकें या संभावित रूप से इस तरह की विधि हो।

"DoSomething स्ट्रिंग हाँ | नहीं"

वहाँ है, तो आप की जरूरत नहीं है Struts, हाइबरनेट, स्प्रिंग और अपाचे libs की तरह ओएस परियोजनाओं (बस कुछ ही उल्लेख करने के लिए) में कोड के इस प्रकार के बहुत सारे हैं शून्य से शुरु करो।

बीटीडब्ल्यू। मैंने उपर्युक्त कोड संकलित नहीं किया है, लेकिन मुझे पूरा यकीन है कि यह छोटे बदलावों के साथ काम करता है, इसके लिए मुझे वोट न दें।

+0

यह वही है साथ ही ObjectInputStream के अंदर किया जाता है , यह बस एक forName() लुकअप करता है और यदि यह क्लास नॉटफाउंड अपवाद फेंकता है, तो नक्शा लुकअप करता है। – Robin

+0

उत्तर के लिए धन्यवाद। मैं स्प्रिंग क्लासयूटिल्स में उपयोगिता विधि का पुन: उपयोग करूंगा जो इस लुकअप प्रक्रिया का उपयोग करता है। –

+1

आप इस "निम्न स्तर" कोड का उपयोग कर रहे हैं? अपनी सेवा को सुरक्षित करने के तरीके पर गहराई से नज़र डालें, अन्यथा आपको अपने रिमोट क्लाइंट से कुछ "System.exit()" कॉल मिल सकती है, और मेरा मानना ​​है कि सर्वर बंद हो जाएगा! – OscarRyz

3

कक्षा तरीकों की एक संख्या दुर्भाग्य से एक सुसंगत फैशन में पुरातन संभाल नहीं है। नाम के लिए इस के आसपास एक आम तरीका है जैसे टेबल;

private static final Map<String, Class> BUILT_IN_MAP = 
    new ConcurrentHashMap<String, Class>(); 

static { 
    for (Class c : new Class[]{void.class, boolean.class, byte.class, char.class, 
      short.class, int.class, float.class, double.class, long.class}) 
     BUILT_IN_MAP.put(c.getName(), c); 
} 

public static Class forName(String name) throws ClassNotFoundException { 
    Class c = BUILT_IN_MAP.get(name); 
    if (c == null) 
     // assumes you have only one class loader! 
     BUILT_IN_MAP.put(name, c = Class.forName(name)); 
    return c; 
} 
2

कैसे एक आदिम प्रकार कौन है फ़ील्ड नाम से जाना जाता है, उदाहरण के लिए के वर्ग पाने के लिए के बारे में निम्नलिखित कोड वार्ता इस मामले में 'sampleInt'।

public class CheckPrimitve { 
    public static void main(String[] args) { 
     Sample s = new Sample(); 
     try { 
      System.out.println(s.getClass().getField("sampleInt").getType() == int.class); // returns true 
      System.out.println(s.getClass().getField("sampleInt").getType().isPrimitive()); // returns true 
     } catch (NoSuchFieldException e) {   
      e.printStackTrace(); 
     } catch (SecurityException e) { 
      e.printStackTrace(); 
     }  
    } 
} 

class Sample { 
    public int sampleInt; 
    public Sample() { 
     sampleInt = 10; 
    } 
} 

एक भी देख सकते हैं कि किसी दिए गए मूल्य आदिम या उस संबंधित आवरण वर्ग हो रही द्वारा है नहीं है या यह फ़ील्ड मान है।

public class CheckPrimitve { 
     public static void main(String[] args) { 
      int i = 3; 
      Object o = i; 
      System.out.println(o.getClass().getSimpleName().equals("Integer")); // returns true 
      Field[] fields = o.getClass().getFields(); 
      for(Field field:fields) { 
       System.out.println(field.getType()); // returns {int, int, class java.lang.Class, int} 
      } 
     } 
    } 
+0

उत्तर पोस्ट करने के लिए धन्यवाद! जबकि एक कोड स्निपेट सवाल का जवाब दे सकता है, फिर भी कुछ अतिरिक्त जानकारी, जैसे व्याख्या, इत्यादि जोड़ने के लिए अभी भी बहुत अच्छा है .. – j0k

+0

@ j0k मैंने कोड में स्पष्टीकरण जोड़ा है। कृपया जांचें। – Arham

+0

यह बहुत बेहतर है, धन्यवाद – j0k

0

गूगल अमरूद सामान की इस तरह के लिए com.google.common.primitives.Primitives प्रदान करता है।

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