2012-03-27 5 views
8

मेरे पास कुछ मूल्य के साथ एक स्ट्रिंग है। मैं एक विशिष्ट विधि को कॉल करने वाले पैकेज में सभी वर्गों पर पुन: प्रयास करना चाहता हूं, और यदि विधि द्वारा लौटाया गया मान मेरे स्ट्रिंग में मान के बराबर है, तो उस वर्ग का ऑब्जेक्ट बनाएं।प्रतिबिंब के साथ एक पैकेज के अंदर सभी कक्षाओं पर संभव है?

मैं इसे गतिशील तरीके से करना चाहता हूं, इसलिए यदि मैं इस पैकेज में एक वर्ग जोड़ता हूं, तो यह स्वचालित रूप से पुनरावृत्ति में होगा।

क्या यह संभव है? यदि नहीं, तो मैं क्या करना चाहता हूं?


मुझे कुछ ऐसा करने की उम्मीद थी।

for(Class clazz: SomeClass.listClasses("org.package")){ 
    //code here 
} 
+0

"इस पैकेज में एक वर्ग का मतलब क्या है"? यह जावा प्रक्रिया के कक्षा में कैसे मिलता है? –

+0

@ जेफरी मैं प्रतिबिंब के बारे में पढ़ रहा था और मुझे लगता है कि यह एकमात्र तरीका है, लेकिन मुझे प्रतिबिंब के बारे में कुछ नहीं पता है। मैंने उस पैकेज में मौजूद प्रत्येक वर्ग के लिए एक सत्यापन जोड़ने के "सामान्य तरीके" की कोशिश की, लेकिन मैं इस तरह से नहीं चाहता क्योंकि यह विस्तार योग्य नहीं है। –

+0

@MiserableVariable विकास के समय में, मैं पैकेज में कुछ नई कक्षा जोड़ता हूं (सभी वर्ग दस्तावेज़ नामक एक अमूर्त वर्ग को बढ़ाते हैं)। –

उत्तर

8

नहीं, यह पूरी तरह से विश्वसनीय तरीके से संभव नहीं है; हालांकि, कई मामलों में इसे लागू करना व्यावहारिक हो सकता है।

जावा क्लास लोडर की लचीलापन के कारण, किसी विशेष पैकेज के तहत परिभाषित कक्षाओं को रनटाइम पर नहीं जाना जा सकता है (उदाहरण के लिए एक विशेष क्लासलोडर पर विचार करें जो कक्षाओं को ऑन-द-फ्लाई परिभाषित करता है, शायद उन्हें नेटवर्क से लोड करके, या उन्हें विज्ञापन-प्रसारित करना)। इस प्रकार, कोई मानक जावा एपीआई नहीं है जो आपको कक्षा में कक्षाओं को सूचीबद्ध करने की अनुमति देती है।

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

Map<String, Set<String>> classesInPackage = new HashMap(); 
for (String entry : eachClasspathEntry()) { 
    if (isClassFile(entry)) { 
    String packageName = getPackageName(entry); 
    if (!classesInPackage.containsKey(packageName)) { 
     classesInPackage.put(packageName, new HashSet<String>()); 
    } 
    classesInPackage.get(packageName).add(getClassName(entry)); 
    } else if (isJarOrZipFile(entry)) { 
    // Do the same for each JAR/ZIP file entry... 
    } 
} 
classesInPackage.get("com.foo.bar"); // => Set<String> of each class... 
+0

लेकिन एक कस्टम क्लासलोडर कम से कम सिद्धांत में हो सकता है। –

+0

@MiserableVariable: कल्पना करें कि मैंने एक कस्टम क्लासलोडर लिखा है जो एक कक्षा के लिए बाइटकोड लौटकर 'defineClass (स्ट्रिंग) 'विधि लागू करता है जो दिए गए वर्ग के नाम से खाली कक्षा को परिभाषित करता है। यह एक पूरी तरह से वैध क्लासलोडर है और प्रत्येक वर्ग को सूचीबद्ध करने के लिए कोई (व्यावहारिक) तरीका नहीं है जिसे परिभाषित किया जा सकता है। – maerics

+0

हां, आम तौर पर समस्या हल करने योग्य नहीं है। लेकिन यह विशिष्ट संकीर्ण स्थिति के लिए अलग है - मैं फ़ोल्डर नाम 'प्लगइन्स' में सभी .class फ़ाइलों को देखना चाहता हूं और प्रत्येक श्रेणी पर एक उदाहरण बना सकता हूं जिसमें 'रजिस्टर' विधि हो। –

1

हाँ, लेकिन सामान्य केस समाधान के रूप में नहीं। आपको अपना कोड पैकेज करना होगा और विशेष रूप से JVM को आमंत्रित करना होगा। विशेष रूप से, आपको एक इंस्ट्रुमेंटेशन एजेंट बनाना होगा, और java.lang.instrument.Instrumentation.getAllLoadedClasses() पर कॉल करना होगा।

पैकेज documentation for java.lang.instrument में एजेंट को बनाने और तुरंत चालू करने के बारे में बहुत सारे विवरण हैं।

+0

वह केवल वर्गों को लोड नहीं करना चाहता है, लेकिन (संभवतः) कक्षापैथ –

+0

में किसी फ़ोल्डर में गिराए गए किसी भी नए वर्ग की फाइलें @ मिस्सेबल वैरिएबल मुझे नहीं पता कि यह स्पष्ट है या नहीं, लेकिन जिन वर्गों को मैं लोड करना चाहता हूं उन्हें विकास समय में परिभाषित किया गया है, नहीं रनटाइम में –

2

मैं आपकी समस्या को हल करने के दो तरीकों के बारे में सोच सकता हूं, हालांकि पैकेज में सभी कक्षाओं में वास्तव में पुन: सक्रिय नहीं होता है।

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

दूसरा विकल्प किसी प्रसिद्ध स्थान पर .class फ़ाइलों को देखना है - एक फ़ोल्डर या फ़ोल्डर का एक सेट कहें - और अनुमान लगाएं कि कक्षा का नाम क्या होगा और इसे लोड करें। यदि यह एक साधारण विकास प्रक्रिया है, तो एक पैकेज से क्लासफ़ाइल शायद एक निर्देशिका में हैं।

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