2012-03-13 16 views
5

के साथ जावा उदाहरण मुझे छोटी समस्या है। मैं जावा एसई सीखता हूं और कक्षा क्लासलोडर ढूंढता हूं। मैं इसे नीचे कोड में उपयोग करने का प्रयास करता हूं: मैं रनटाइम पर कक्षा को गतिशील रूप से लोड करने के लिए URLClassLoader का उपयोग करने का प्रयास कर रहा हूं।क्लासलोडर

URLClassLoader urlcl = new URLClassLoader(new URL[] {new URL("file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar")}); 
Class<?> classS = urlcl.loadClass("michal.collection.Stack"); 
for(Method field: classS.getMethods()) { 
    System.out.println(field.getName()); 
} 
Object object = classS.newInstance(); 
michal.collection.Stack new_name = (michal.collection.Stack) object; 

जावा आभासी मशीन मुझे वर्ग को नहीं देखती है, और मैं निम्न अपवाद प्राप्त करें:

Exception in thread "main" java.lang.Error: Unresolved compilation problems: michal cannot be resolved to a type michal cannot be resolved to a type at Main.main(Main.java:62) 

आप जानते हैं कि कैसे मैं इस समस्या को हल कर सकते हैं करते हैं?

+0

क्या आप अपवाद और स्टैक ट्रेस पोस्ट कर सकते हैं जो आपको मिलता है? बेशक – Shaunak

+0

: सूत्र में "मुख्य" java.lang.Error अपवाद: समाधान नहीं किया गया संकलन समस्याओं: \t मीकल एक प्रकार \t मीकल को हल नहीं किया जा सकता है एक प्रकार \t Main.main (Main.java में करने के लिए हल नहीं किया जा सकता है: 62) –

उत्तर

4
Class<?> classS = urlcl.loadClass("michal.collection.Stack"); 
[...] 
Object object = classS.newInstance(); 
michal.collection.Stack new_name = (michal.collection.Stack) object; 

तो आप गतिशील रूप से कक्षा को लोड करने का प्रयास कर रहे हैं और फिर आप इसे संदर्भित करते हैं। यदि आप पहले से ही इसे स्थिर रूप से लिंक कर सकते हैं, तो यह लोड हो गया है और आप इसे फिर से लोड नहीं कर सकते हैं। आपको प्रतिबिंब द्वारा विधियों तक पहुंचने की आवश्यकता होगी।

आमतौर पर आप क्या करेंगे आमतौर पर लोड वर्ग क्लास क्लास लोडर से एक इंटरफ़ेस लागू करता है। एक उदाहरण के बाद (आमतौर पर केवल एक ही उदाहरण) बनाया जाता है, तो आप इंटरफ़ेस के प्रकार के संदर्भ में इसका संदर्भ ले सकते हैं।

public interface Stack { 
    [...] 
} 
[...] 
    URLClassLoader urlcl = URLClassLoader.newInstance(new URL[] { 
     new URL(
      "file:///I:/Studia/PW/Sem6/_repozytorium/workspace/Test/testJavaLoader.jar" 
     ) 
    }); 
    Class<?> clazz = urlcl.loadClass("michal.collection.StackImpl"); 
    Class<? extends Stack> stackClass = clazz.asSubclass(Stack.class); 
    Constructor<? extends Stack> ctor = stackClass.getConstructor(); 
    Stack stack = ctor.newInstance(); 

(सामान्य स्टैक ओवरफ़्लो के बारे में इतना नहीं संकलन के रूप में त्याग।)

आप स्वाद के लिए से निपटने त्रुटि जोड़ने की आवश्यकता होगी। URLClassLoader.newInstanceURLClassLoader पर कुछ परिशोधन जोड़ता है। Class.newInstance पूरी तरह से अपवाद हैंडलिंग टूट गया है और इससे बचा जाना चाहिए।

+0

तो मैं इस वर्ग से विधि का उपयोग कैसे कर सकता हूं? –

+0

@ user1267483 आपको उस प्रोजेक्ट में एक इंटरफ़ेस बनाना होगा जिसे आप URL के लिए URLClassloader का उपयोग कर रहे हैं, जो कि आपके michal.collection.Stack उपकरण। –

+0

@ user1267483 नोट, मैंने 'स्टैक' का नाम 'स्टैकआईएमपीएल' (सबसे अच्छा नाम नहीं, लेकिन पारंपरिक) का नाम बदल दिया है, और एक नया इंटरफ़ेस 'स्टैक' पेश किया है। –

0

आप कोड में नाम से गतिशील रूप से लोड प्रकार का उल्लेख नहीं कर सकते हैं, क्योंकि इसे संकलन-समय पर हल किया जाना है। से Class ऑब्जेक्ट के newInstance() फ़ंक्शन का उपयोग करने की आवश्यकता होगी।

+1

ओपी 'क्लास' ऑब्जेक्ट पर 'classClass' से' class.newInstance' का उपयोग कर रहा है। –

0

उपरोक्त उत्तरों दोनों गलत हैं, वे मूल समस्या को समझ नहीं पाते हैं। आपका मुख्य स्टैक क्लास को संदर्भित करता है जिसे एक वर्ग लोडर द्वारा लोड किया गया था। आपका urlclassloader एक ही नाम के साथ एक वर्ग लोड करने का प्रयास कर रहा है। आप लोड किए गए को संदर्भित नहीं कर सकते क्योंकि वे समान नहीं हैं, वे अलग-अलग क्लासलोडर्स से संबंधित हैं। आप अलग-अलग देखने के लिए प्रत्येक के कोड को प्रिंट कर सकते हैं। एक समानता परीक्षण भी क्लास संदर्भों को अलग होने के लिए दिखाएगा। आपकी समस्या शायद इसलिए है क्योंकि sstack द्वारा संदर्भित निर्भर वर्गों को पाया जा सकता है, जो NoClassDefErrors आदि में rsukt होगा। आपका मुख्य संभवतः क्लासकास्टेसेप्शन के साथ विफल हो जाएगा।

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