जवाबों:
हो सकता है कि दोनों तरीकों का उपयोग कैसे किया जाए, यह प्रदर्शित करने वाला एक उदाहरण आपको चीजों को बेहतर ढंग से समझने में मदद करेगा। तो, निम्न वर्ग पर विचार करें:
package test;
public class Demo {
public Demo() {
System.out.println("Hi!");
}
public static void main(String[] args) throws Exception {
Class clazz = Class.forName("test.Demo");
Demo demo = (Demo) clazz.newInstance();
}
}
जैसा कि इसके javadoc में बताया गया है, दिए गए स्ट्रिंग नाम के साथ वर्ग या इंटरफ़ेस से संबंधित ऑब्जेक्ट को कॉल करता है अर्थात यह रिटर्न करता है जो प्रकार के चर पर प्रभावित होता है ।Class.forName(String)
Class
test.Demo.class
clazz
Class
फिर, कॉलिंग इस ऑब्जेक्ट द्वारा दर्शाए गए वर्ग का एक नया उदाहरण बनाता है । क्लास को तत्काल किया जाता है जैसे कि एक खाली तर्क सूची के साथ एक अभिव्यक्ति द्वारा । दूसरे शब्दों में, यह वास्तव में यहाँ के बराबर है और एक नया उदाहरण देता है ।clazz.newInstance()
Class
new
new Demo()
Demo
और इस Demo
वर्ग को चलाने से निम्न आउटपुट प्रिंट होता है:
Hi!
पारंपरिक के साथ बड़ा अंतर यह new
है कि newInstance
एक वर्ग को तुरंत चलाने की अनुमति देता है जिसे आप रनटाइम तक नहीं जानते हैं, जिससे आपका कोड अधिक गतिशील हो जाता है।
एक विशिष्ट उदाहरण JDBC API है जो रनटाइम के दौरान, कार्य करने के लिए आवश्यक सटीक ड्राइवर को लोड करता है। EJBs कंटेनर, सर्वलेट कंटेनर अन्य अच्छे उदाहरण हैं: वे गतिशील रनटाइम लोडिंग का उपयोग लोड करने और घटकों को बनाने के लिए करते हैं, जो रनटाइम से पहले कुछ भी नहीं जानते हैं।
दरअसल, अगर आप और आगे जाना चाहते हैं, तो टेड न्यूर्ड पेपर अंडरस्टैंडिंग क्लास.forName () पर एक नज़र डालें, जो कि मैं ऊपर दिए गए पैराग्राफ में देख रहा था।
EDIT (टिप्पणी के रूप में पोस्ट किए गए ओपी से एक प्रश्न का उत्तर): जेडीबीसी ड्राइवरों का मामला थोड़ा खास है। जैसा कि JDBC API के साथ आरंभ करने के DriverManager अध्याय में बताया गया है :
(...) एक
Driver
कक्षा भरी हुई है, और इसलिएDriverManager
दो तरीकों में से एक में स्वचालित रूप से पंजीकृत है:
विधि को बुलाकर
Class.forName
। यह स्पष्ट रूप से चालक वर्ग को लोड करता है। चूंकि यह किसी भी बाहरी सेटअप पर निर्भर नहीं करता है, ड्राइवर को लोड करने का यह तरीकाDriverManager
फ्रेमवर्क का उपयोग करने के लिए अनुशंसित है । निम्नलिखित कोड कक्षा को लोड करता हैacme.db.Driver
:Class.forName("acme.db.Driver");
यदि
acme.db.Driver
ऐसा लिखा गया है, तो इसे लोड करने से एक उदाहरण बनता है औरDriverManager.registerDriver
उस उदाहरण के साथ पैरामीटर (जैसा कि यह करना चाहिए) के रूप में कॉल किया जाता है, फिर यहDriverManager
ड्राइवरों की सूची में है और कनेक्शन बनाने के लिए उपलब्ध है।(...)
इन दोनों मामलों में, यह नव-भारित
Driver
वर्ग की जिम्मेदारी है कि वह कॉल करके खुद को पंजीकृत करेDriverManager.registerDriver
। जैसा कि उल्लेख किया गया है, यह स्वचालित रूप से तब किया जाना चाहिए जब कक्षा लोड हो।
आरंभीकरण के दौरान खुद को पंजीकृत करने के लिए, JDBC ड्राइवर आमतौर पर इस तरह एक स्थैतिक आरंभीकरण ब्लॉक का उपयोग करते हैं:
package acme.db;
public class Driver {
static {
java.sql.DriverManager.registerDriver(new Driver());
}
...
}
कॉलिंग कक्षा Class.forName("acme.db.Driver")
के आरंभीकरण का कारण बनता है acme.db.Driver
और इस प्रकार स्थैतिक आरंभीकरण ब्लॉक का निष्पादन होता है। और Class.forName("acme.db.Driver")
वास्तव में एक उदाहरण "पैदा" करेगा लेकिन यह सिर्फ एक परिणाम है कि कैसे (अच्छे) JDBC ड्राइवर को लागू किया जाता है।
एक साइड नोट के रूप में, मैं उल्लेख करूंगा कि यह सब अब JDBC 4.0 (जावा 7 के बाद से डिफ़ॉल्ट पैकेज के रूप में जोड़ा गया) और JDBC 4.0 ड्राइवरों के नए ऑटो-लोडिंग फ़ीचर के साथ आवश्यक नहीं है। जावा SE 6 में JDBC 4.0 संवर्द्धन देखें ।
DriverManager.registerDriver
। Class.forName
JDBC ड्राइवर पर कॉल करना इसकी शुरुआत का कारण बनता है और इस प्रकार स्टैटिक ब्लॉक का निष्पादन होता है। उदाहरण के लिए java2s.com/Open-Source/Java-Document/Database-DBMS/… पर एक नज़र डालें । तो यह वास्तव में ड्राइवर इंटर्न के कारण एक विशेष मामला है।
Class.forName () आपको क्लास ऑब्जेक्ट देता है, जो प्रतिबिंब के लिए उपयोगी है। जिन तरीकों से इस ऑब्जेक्ट को जावा द्वारा परिभाषित किया गया है, न कि प्रोग्रामर द्वारा कक्षा लिखने से। वे हर वर्ग के लिए समान हैं। उस पर newInstance () कॉल करना आपको उस वर्ग का एक उदाहरण देता है (अर्थात कॉलिंग कॉलिंग के Class.forName("ExampleClass").newInstance()
बराबर है new ExampleClass()
), जिस पर आप उन तरीकों को कॉल कर सकते हैं जिन्हें क्लास परिभाषित करता है, दृश्यमान फ़ील्ड एक्सेस करता है आदि।
JDBC दुनिया में, सामान्य अभ्यास (JDBC API के अनुसार) यह है कि आप Class#forName()
JDBC ड्राइवर को लोड करने के लिए उपयोग करते हैं। JDBC ड्राइवर को DriverManager
स्थैतिक ब्लॉक के अंदर खुद को पंजीकृत करना चाहिए :
package com.dbvendor.jdbc;
import java.sql.Driver;
import java.sql.DriverManager;
public class MyDriver implements Driver {
static {
DriverManager.registerDriver(new MyDriver());
}
public MyDriver() {
//
}
}
लागू Class#forName()
सभी निष्पादित करेंगे स्थिर initializers । इस तरह DriverManager
से कनेक्शनधारी URL के द्वारा पंजीकृत ड्राइवरों के बीच संबंधित ड्राइवर को खोजा जा सकता है, getConnection()
जिसके दौरान लगभग निम्न प्रकार दिखाई देते हैं:
public static Connection getConnection(String url) throws SQLException {
for (Driver driver : registeredDrivers) {
if (driver.acceptsURL(url)) {
return driver.connect(url);
}
}
throw new SQLException("No suitable driver");
}
लेकिन बग्गी JDBC ड्राइवर भी थे org.gjt.mm.mysql.Driver
, जो पहले से ही ज्ञात उदाहरण के साथ शुरू होते हैं , जो एक स्थिर ब्लॉक के बजाय कंस्ट्रक्टर के अंदर गलत तरीके से पंजीकृत होता है :
package com.dbvendor.jdbc;
import java.sql.Driver;
import java.sql.DriverManager;
public class BadDriver implements Driver {
public BadDriver() {
DriverManager.registerDriver(this);
}
}
इसे गतिशील रूप से काम करने का एकमात्र तरीका newInstance()
बाद में कॉल करना है! अन्यथा आप पहली नज़र में अस्पष्टनीय "SQLException: no उपयुक्त ड्राइवर" का सामना करेंगे। एक बार फिर, यह JDBC ड्राइवर में एक बग है, आपके अपने कोड में नहीं। आजकल, किसी भी JDBC ड्राइवर को इस बग को शामिल नहीं करना चाहिए। तो आप कर सकते हैं (और चाहिए) newInstance()
दूर छोड़ दें ।
1: यदि आप केवल क्लास के स्टैटिक ब्लॉक में रुचि रखते हैं, तो क्लास को लोड करना ही होगा, और स्टैटिक ब्लॉक को निष्पादित करेगा, इसके बाद आपको बस जरूरत है:
Class.forName("Somthing");
2: यदि आप कक्षा को लोड करने में रुचि रखते हैं, तो इसके स्टैटिक ब्लॉक को निष्पादित करें और इसके नॉन स्टैटिक भाग को एक्सेस करना चाहते हैं, तो आपको एक उदाहरण की आवश्यकता है और फिर आपको इसकी आवश्यकता है:
Class.forName("Somthing").newInstance();
"Class.forName ()" दिए गए नाम के लिए क्लास-प्रकार लौटाता है। "newInstance ()" इस वर्ग का एक उदाहरण देता है।
प्रकार पर आप सीधे किसी भी उदाहरण के तरीकों को नहीं कह सकते, लेकिन केवल कक्षा के लिए प्रतिबिंब का उपयोग कर सकते हैं। यदि आप कक्षा के किसी ऑब्जेक्ट के साथ काम करना चाहते हैं, तो आपको इसका एक उदाहरण बनाना होगा (उसी तरह "नए MyClass ()") को कॉल करना।
"Class.forName ()" के लिए उदाहरण
Class myClass = Class.forName("test.MyClass");
System.out.println("Number of public methods: " + myClass.getMethods().length);
उदाहरण के लिए "Class.forName ()। newInstance ()"
MyClass myClass = (MyClass) Class.forName("test.MyClass").newInstance();
System.out.println("String representation of MyClass instance: " + myClass.toString());
उपरोक्त उत्तरों को जोड़ने पर, जब हमारे पास एक स्थिर कोड (यानी कोड ब्लॉक स्वतंत्र है), जिसे मेमोरी में मौजूद रहने की आवश्यकता है, तो हम कक्षा में वापस आ सकते हैं इसलिए हम Class.forname ("someName") का उपयोग करेंगे यदि हम स्टैटिक कोड न होने के कारण हम Class.forname ()। newInstance ("someName") के लिए जा सकते हैं क्योंकि यह ऑब्जेक्ट लेवल कोड ब्लॉक (नॉन स्टैटिक) को मेमोरी में लोड करेगा
कोई फर्क नहीं पड़ता कि आप कितनी बार Class.forName () पद्धति को कॉल करते हैं, केवल एक बार स्थिर ब्लॉक निष्पादित होने पर कई बार नहीं:
पैकेज forNameMethodDemo;
सार्वजनिक वर्ग मेनक्लास {
public static void main(String[] args) throws Exception {
Class.forName("forNameMethodDemo.DemoClass");
Class.forName("forNameMethodDemo.DemoClass");
Class.forName("forNameMethodDemo.DemoClass");
DemoClass demoClass = (DemoClass)Class.forName("forNameMethodDemo.DemoClass").newInstance();
}
}
पब्लिक क्लास डेमोक्लास {
static {
System.out.println("in Static block");
}
{
System.out.println("in Instance block");
}
}
आउटपुट होगा:
in Static block
in Instance block
यह in Static block
कथन केवल एक बार नहीं तीन बार छपा है।
Class.forName () -> forName () क्लास क्लास की स्टैटिक विधि है, जो क्लास क्लास ऑब्जेक्ट को रिफ्लेक्ट करती है, न कि क्लास क्लास ऑब्जेक्ट का इस्तेमाल किया जाता है, इसलिए आप केवल क्लास क्लास के तरीकों को इस पर कॉल कर सकते हैं जैसे getMethods (), getConstructors () आदि।
यदि आप अपने (केवल रनटाइम) वर्ग के स्थिर ब्लॉक को चलाने के बारे में परवाह करते हैं और केवल अपनी कक्षा के तरीकों, निर्माणकर्ताओं, संशोधक आदि की जानकारी प्राप्त कर रहे हैं, तो आप इस ऑब्जेक्ट के साथ कर सकते हैं जिसे आप Class.forName () का उपयोग करके प्राप्त करते हैं
लेकिन अगर आप अपने क्लास मेथड (उस क्लास की क्लास को एक्सेस या कॉल करना चाहते हैं जो आपने रनटाइम में दी है) तो आपको उसकी ऑब्जेक्ट की जरूरत है इसलिए क्लास क्लास का न्यू इनस्टेंस मेथड आपके लिए है। यह क्लास का नया इंस्टेंस बनाएं और उसे आपको लौटा दें। .आपको इसे अपनी कक्षा में टाइप करने की जरूरत है।
ex-: मान लीजिए कि कर्मचारी आपकी कक्षा का है
कक्षा a = Class.forName (args [0]);
// args [0] = रनटाइम पर क्लास देने के लिए cmd लाइन तर्क।
कर्मचारी ob1 = a.newInstance ();
a.newInstance () नए कर्मचारी () का उपयोग करके ऑब्जेक्ट बनाने के समान है।
अब आप अपने सभी कक्षा दृश्य क्षेत्रों और विधियों का उपयोग कर सकते हैं।