क्या जावा में नाम से एक क्लास को तत्काल करने का एक तरीका है?


102

मैं इस प्रश्न के रूप में देख रहा था: अपने स्ट्रिंग नाम से एक वर्ग को तुरंत लिखिए जो यह बताता है कि किसी वर्ग को उसका नाम होने पर कैसे त्वरित रूप से लिखा जाए। क्या जावा में ऐसा करने का कोई तरीका है? मेरे पास पैकेज का नाम और वर्ग का नाम होगा और मुझे उस विशेष नाम वाले ऑब्जेक्ट को बनाने में सक्षम होने की आवश्यकता है।


हम एक वर्ग को तुरंत लिखते हैं और परिणाम एक वस्तु (या: उदाहरण ) है।
एंड्रियास डॉक

1
इसका उत्तर हां है, लेकिन मुझे लगता है कि आपको यह पूछना चाहिए कि क्या यह एक अच्छा विचार है। महान शक्ति (प्रतिबिंब) के साथ महान जिम्मेदारी आती है और आपको इसका उपयोग केवल तभी करना चाहिए जब आप समझें और परिणामों पर विचार करें।
c1moore

जवाबों:


238

दो तरीके:

विधि 1 - केवल उन वर्गों के लिए जिनके पास नो-आर्ग कंस्ट्रक्टर है

यदि आपकी कक्षा में एक नो-आर्ग कंस्ट्रक्टर है, तो आप एक इंस्टेंस का उपयोग Classकरके एक ऑब्जेक्ट प्राप्त कर सकते हैं Class.forName()और newInstance()एक इंस्टेंस बनाने के लिए उपयोग कर सकते हैं (हालांकि सावधान रहें कि इस विधि को अक्सर बुराई माना जाता है क्योंकि यह जावा के चेक किए गए अपवादों को हरा सकता है)।

उदाहरण के लिए:

Class<?> clazz = Class.forName("java.util.Date");
Object date = clazz.newInstance();

विधि 2

एक वैकल्पिक सुरक्षित दृष्टिकोण जो भी काम करता है यदि वर्ग में कोई नो-आर्ग कंस्ट्रक्टर नहीं है, तो अपनी ऑब्जेक्ट को प्राप्त करने के लिए अपनी क्लास ऑब्जेक्ट को क्वेरी करें Constructorऔर newInstance()इस ऑब्जेक्ट पर एक विधि कॉल करें :

Class<?> clazz = Class.forName("com.foo.MyClass");
Constructor<?> constructor = clazz.getConstructor(String.class, Integer.class);
Object instance = constructor.newInstance("stringparam", 42);

दोनों तरीकों को प्रतिबिंब के रूप में जाना जाता है । आपको आमतौर पर विभिन्न अपवादों को पकड़ना होगा जो कि हो सकते हैं, जैसे कि चीजें:

  • JVM आपकी कक्षा को लोड नहीं कर सकता है या नहीं कर सकता है
  • जिस कक्षा में आप तात्कालिक प्रयास कर रहे हैं, उसके पास सही प्रकार के निर्माता नहीं हैं
  • कंस्ट्रक्टर ने खुद एक अपवाद फेंक दिया
  • जिस निर्माता को आप आमंत्रित करने का प्रयास कर रहे हैं वह सार्वजनिक नहीं है
  • एक सुरक्षा प्रबंधक स्थापित किया गया है और प्रतिबिंब को होने से रोक रहा है

नमस्ते, एक बार जब हमने ऑब्जेक्ट बनाया है newInstance(), तो क्या हम इसे वापस अपनी वस्तु में डाल सकते हैं?
GMsoF

@Simon क्या आप सुरक्षा प्रबंधक के बारे में विस्तृत / संकेत दे सकते हैं?
राम

मुझे यह समझ में नहीं आता है। मैं किसी अन्य निर्देशिका में एक अज्ञात फ़ाइल में एक वर्ग का उपयोग करना चाहता हूं, मेरे पास केवल एक स्ट्रिंग के रूप में पथ / फ़ाइल का नाम है। स्ट्रिंग "dir / unkonwn.java"। Class.forName ("dir / अज्ञात") को कॉल करना मुझे त्रुटियाँ देता है।
जॉन ktejik

हम कैसे डाल सकता instanceकरने के लिए com.foo.MyClass? यह बताया कि com.foo.MyClass सिर्फ एक स्ट्रिंग है
Sanket9394

14
MyClass myInstance = (MyClass) Class.forName("MyClass").newInstance();

15
यह ध्यान देने योग्य है कि यह काम नहीं करता है यदि वर्ग में कोई पैरामीटर रहित निर्माता नहीं है (और अन्य निर्माणकर्ता हैं), या यदि पैरामीटर रहित निर्माता अप्राप्य है।
दाऊद इब्न करीम

3

उपयोग Class.forName ( "वर्ग की स्ट्रिंग नाम") newInstance ()।;

Class.forName("A").newInstance();

यह ए इनिशियलाइज़्ड नाम के वर्ग का कारण बनेगा।


मेरे लिए काम नहीं करता है, यहां तक ​​कि पैकेज के नाम के साथ पहले से ही लिखा हुआ है। :(
trusktr

3

एक उदाहरण का उपयोग करने के लिए एक वर्ग का पूरी तरह से योग्य नाम प्राप्त करना आसान बनाने के लिए Class.forName(...), कोई भी Class.getName()विधि का उपयोग कर सकता है । कुछ इस तरह:

class ObjectMaker {
    // Constructor, fields, initialization, etc...
    public Object makeObject(Class<?> clazz) {
        Object o = null;

        try {
            o = Class.forName(clazz.getName()).newInstance();
        } catch (ClassNotFoundException e) {
            // There may be other exceptions to throw here, 
            // but I'm writing this from memory.
            e.printStackTrace();
        }

        return o;
    }
}

फिर आप जिस वस्तु को प्राप्त करते हैं, उसे आप जिस भी वर्ग में वापस ला सकते हैं, उसमें डाल सकते हैं makeObject(...):

Data d = (Data) objectMaker.makeObject(Data.class);

1
आप बस नहीं कर सकते clazz.newInstance()करने के बजाय getNameउसके बाद fromName?
user276648

1

जावा प्रतिबिंब का उपयोग करें

नई वस्तुएं बनाना कंस्ट्रक्टरों के लिए विधि आह्वान के बराबर नहीं है, क्योंकि एक निर्माणकर्ता को आमंत्रित करना एक नई वस्तु बनाने के बराबर है (सबसे सटीक होने के लिए, एक नई वस्तु बनाने में मेमोरी आवंटन और ऑब्जेक्ट निर्माण दोनों शामिल हैं)। तो पिछले उदाहरण के निकटतम निकटतम कहना है:

import java.lang.reflect.*;

   public class constructor2 {
      public constructor2()
      {
      }

      public constructor2(int a, int b)
      {
         System.out.println(
           "a = " + a + " b = " + b);
      }

      public static void main(String args[])
      {
         try {
           Class cls = Class.forName("constructor2");
           Class partypes[] = new Class[2];
            partypes[0] = Integer.TYPE;
            partypes[1] = Integer.TYPE;
            Constructor ct 
              = cls.getConstructor(partypes);
            Object arglist[] = new Object[2];
            arglist[0] = new Integer(37);
            arglist[1] = new Integer(47);
            Object retobj = ct.newInstance(arglist);
         }
         catch (Throwable e) {
            System.err.println(e);
         }
      }
   }

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




0

कुछ इस तरह से काम करना चाहिए ...

String name = "Test2";//Name of the class
        Class myClass = Class.forName(name);
        Object o = myClass.newInstance();

0

newInstance()सीधे जावा 8 के रूप में उपयोग किया जाता है। आपको Class.getDeclaredConstructor(...).newInstance(...)संबंधित अपवादों के साथ उपयोग करने की आवश्यकता है।

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