दिलचस्प पोस्ट
जावा 8 स्थानीय डेटटाइम और हाइबरनेट 4 क्या मुझे कंट ऑब्जेक्ट के लिए उपयोगकर्ता द्वारा प्रदत्त कंस्ट्रक्टर को वास्तव में लागू करना है? पता कैसे करें कि विंडोज बंद हो रहा है या पुनरारंभ हो रहा है सी ++ में नए ऑपरेटर के साथ मेमोरी कैसे आरंभ करें? ScrollView में चित्रों की ग्रिड फाइल कैसे एक जीआईटी रेपो से दूसरे (एक क्लोन नहीं) दूसरे स्थान पर, इतिहास को संरक्षित करने के लिए VB.NET 'के साथ' विवरण – गले लगाओ या बचें? क्या मैलोक लिज़क्स (और अन्य प्लेटफार्मों) पर आवंटन के लिए बैकिंग पृष्ठ बनाते हैं? अजगर डेकोरेटर के लिए अतिरिक्त तर्क कैसे पास करें? सी # जेआईटी कंपाइलिंग और .नेट यह निर्धारित करने के लिए कि क्या दशमलव / डबल पूर्णांक है? यादृच्छिक क्यों होता है। एकल एम्परसेंड का मतलब क्या है? जावा – मेगा-अक्षरों रेगेक्स में से बचें जावास्क्रिप्ट पर ब्राउजर आँकड़े निष्क्रिय

रनटाइम पर, जावा क्लास में सभी कक्षाएं ढूंढें जो बेस क्लास का विस्तार करती हैं

मैं ऐसा कुछ करना चाहता हूं:

List<Animal> animals = new ArrayList<Animal>(); for( Class c: list_of_all_classes_available_to_my_app() ) if (c is Animal) animals.add( new c() ); 

तो, मैं अपने आवेदन के ब्रह्मांड में सभी वर्गों को देखना चाहता हूं, और जब मुझे पशु से उतरते हैं, तो मैं उस प्रकार का एक नया ऑब्जेक्ट बनाना चाहता हूं और इसे सूची में जोड़ना चाहता हूं। यह मुझे चीजों की एक सूची को अपडेट किए बिना कार्यक्षमता जोड़ने की अनुमति देता है मैं निम्नलिखित से बच सकता हूँ:

 List<Animal> animals = new ArrayList<Animal>(); animals.add( new Dog() ); animals.add( new Cat() ); animals.add( new Donkey() ); ... 

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

अद्यतन करें: 10/16/2008 9:00 पूर्वाह्न मानक समय:

इस प्रश्न ने बहुत सारी प्रतिक्रियाएं उत्पन्न की हैं – धन्यवाद। प्रतिक्रियाओं और मेरे शोध से, मैंने पाया है कि वास्तव में मैं क्या करना चाहता हूं जावा के तहत संभव नहीं है। ऐसे दृष्टिकोण हैं, जैसे डीडीमित्रोव की सर्विसलोडर तंत्र जो काम कर सकते हैं – पर वे जो चाहते हैं, वे बहुत भारी हैं, और मेरा मानना ​​है कि मैं बस जावा कोड से एक बाहरी विन्यास फाइल में समस्या को हल करता हूं।

मैं क्या चाहता हूं यह बताकर एक और तरीका है: मेरे पशु वर्ग में एक स्थिर समारोह पाता है और जानवरों से आने वाले सभी वर्गों को तत्काल प्रदान करता है – बिना किसी और विन्यास / कोडिंग के। अगर मुझे कॉन्फ़िगर करना पड़ता है, तो मैं उन्हें पशु वर्ग में वैसे भी इन्स्तांत कर सकता हूं। मैं समझता हूं कि क्योंकि जावा प्रोग्राम केवल क्लास फाइलों का एक ढीला संघ है, जो कि ऐसा ही है।

दिलचस्प है, ऐसा लगता है कि सी # में यह काफी तुच्छ है।

Solutions Collecting From Web of "रनटाइम पर, जावा क्लास में सभी कक्षाएं ढूंढें जो बेस क्लास का विस्तार करती हैं"

मैं org.reflections का उपयोग करें :

 Reflections reflections = new Reflections("com.mycompany"); Set<Class<? extends MyInterface>> classes = reflections.getSubTypesOf(MyInterface.class); 

आप जो चाहते हैं, उसे करने के लिए जावा तरीका सेवा लोडर तंत्र का उपयोग करना है

इसके अलावा कई लोग एक अच्छी तरह से जाना जाता कक्षा स्थान (यानी /एमएमटीएएएनएफ / सर्विसेज / मैलोग्लिन। प्रॉपर्टीज) में फ़ाइल रखने और उसके बाद क्लासलोडर.गेटरेसिसंस () का इस्तेमाल करते हुए सभी फाइलों को इस नाम से सभी जारों से जोड़ते हैं । यह प्रत्येक जार अपने स्वयं के प्रदाताओं को निर्यात करने की अनुमति देता है और आप उन्हें कक्षा .forName () का उपयोग करके प्रतिबिंब के द्वारा इन्स्तांत कर सकते हैं

इस बारे में एक दृष्टिकोण-उन्मुख दृष्टिकोण से सोचें; आप जो करना चाहते हैं, वास्तव में, सभी वर्गों को रनटाइम में पता है जो ने पशु वर्ग को बढ़ा दिया है (मुझे लगता है कि यह आपके शीर्षक की तुलना में आपकी समस्या का एक थोड़ा अधिक सटीक वर्णन है; अन्यथा, मुझे नहीं लगता कि आपके पास एक रनटाइम सवाल है।)

तो मुझे लगता है कि आप चाहते हैं कि अपने बेस क्लास (एनीमियल) के कन्स्ट्रक्टर को बनाना है जो आपकी स्थिर सरणी में जोड़ता है (मैं ऐरे लेलिस्ट्स पसंद करता हूं, लेकिन हर एक के लिए) मौजूदा क्लास के प्रकार जो तत्काल किया जा रहा है।

तो, मोटे तौर पर;

 public abstract class Animal { private static ArrayList<Class> instantiatedDerivedTypes; public Animal() { Class derivedClass = this.getClass(); if (!instantiatedDerivedClass.contains(derivedClass)) { instantiatedDerivedClass.Add(derivedClass); } } 

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

दुर्भाग्य से यह पूरी तरह से संभव नहीं है क्योंकि कक्षाओलोडर आपको बताएंगे कि कक्षाएं क्या उपलब्ध हैं। आप, हालांकि, इस तरह से कुछ करने में काफी करीब हो सकते हैं:

 for (String classpathEntry : System.getProperty("java.class.path").split(System.getProperty("path.separator"))) { if (classpathEntry.endsWith(".jar")) { File jar = new File(classpathEntry); JarInputStream is = new JarInputStream(new FileInputStream(jar)); JarEntry entry; while( (entry = is.getNextJarEntry()) != null) { if(entry.getName().endsWith(".class")) { // Class.forName(entry.getName()) and check // for implementation of the interface } } } } 

संपादित करें: जॉयंस्टोक सही (टिप्पणियों में) है कि यह केवल स्टैंडअलोन जावा अनुप्रयोगों के लिए काम करता है, और एक अनुप्रयोग सर्वर के तहत काम नहीं करेगा।

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

जो सभी इस सवाल का जवाब दिया धन्यवाद।

ऐसा लगता है कि यह दरअसल कठिन दरार है। मैंने अपना बेस क्लास में एक स्थिर सरणी और गायब बना दिया और समाप्त कर दिया।

 public abstract class Animal{ private static Animal[] animals= null; public static Animal[] getAnimals(){ if (animals==null){ animals = new Animal[]{ new Dog(), new Cat(), new Lion() }; } return animals; } } 

ऐसा लगता है कि जावा को स्वयं-खोज योग्यता के लिए सिर्फ सी # की तरह ही स्थापित नहीं किया गया है मुझे लगता है कि समस्या यह है कि जब से जावा ऐप एक निर्देशिका / जार फ़ाइल में कहीं और। वर्ग फाइलों का संग्रह होता है, तब तक रनटाइम एक वर्ग के बारे में तब तक नहीं जानता जब तक इसका संदर्भ नहीं दिया जाता। उस समय लोडर इसे लोड करता है – जो मैं करने की कोशिश कर रहा हूं वह उस संदर्भ से पहले पता चलता है जो फ़ाइल सिस्टम पर जाने के बिना संभव है और देख रहा है।

मुझे हमेशा कोड पसंद होता है जो मुझे स्वयं के बारे में बताने के बजाय खुद को खोज सकता है, लेकिन यह भी काम करता है।

एक बार फिर धन्यवाद!

आप स्ट्रिप्स फ्रेमवर्क से ResolverUtil ( कच्चे स्रोत ) का उपयोग कर सकते हैं
अगर आपको किसी भी मौजूदा कोड को रिफैक्टर करने के बिना कुछ सरल और त्वरित जरूरत पड़ती है

यहां कोई भी उदाहरण नहीं है जिसमें किसी भी कक्षा को लोड नहीं किया गया है:

 package test; import java.util.Set; import net.sourceforge.stripes.util.ResolverUtil; public class BaseClassTest { public static void main(String[] args) throws Exception { ResolverUtil<Animal> resolver = new ResolverUtil<Animal>(); resolver.findImplementations(Animal.class, "test"); Set<Class<? extends Animal>> classes = resolver.getClasses(); for (Class<? extends Animal> clazz : classes) { System.out.println(clazz); } } } class Animal {} class Dog extends Animal {} class Cat extends Animal {} class Donkey extends Animal {} 

यह एक आवेदन सर्वर में भी काम करता है, क्योंकि वह काम करने के लिए डिज़ाइन किया गया था;)

कोड मूल रूप से निम्न करता है:

  • आपके द्वारा निर्दिष्ट पैकेज (एस) में सभी संसाधनों को पुनरावृत्त करें
  • केवल समाप्त होने वाले संसाधनों में समापन करें। वर्ग
  • ClassLoader#loadClass(String fullyQualifiedName) का उपयोग करके उन कक्षाओं को लोड करें
  • चेक अगर Animal.class.isAssignableFrom(loadedClass);

OpenPojo का उपयोग कर आप निम्न कर सकते हैं:

 String package = "com.mycompany"; List<Animal> animals = new ArrayList<Animal>(); for(PojoClass pojoClass : PojoClassFactory.enumerateClassesByExtendingType(package, Animal.class, null) { animals.add((Animal) InstanceFactory.getInstance(pojoClass)); } 

यह एक कठिन समस्या है और आपको इस जानकारी को स्थिर विश्लेषण का उपयोग करने की आवश्यकता होगी, यह रनटाइम पर आसानी से उपलब्ध नहीं है। असल में अपने ऐप का क्लासपाथ प्राप्त करें और उपलब्ध कक्षाओं के माध्यम से स्कैन करें और एक वर्ग की बाइटकोड जानकारी पढ़िए जिसे यह वर्ग से प्राप्त होता है ध्यान दें कि एक वर्ग डॉग सीधे पशु से नहीं प्राप्त हो सकता है लेकिन पशु से पशु का उत्तराधिकारी हो सकता है, जो कि पशु से निकलता है, इसलिए आपको उस पदानुक्रम का ट्रैक रखने की आवश्यकता होगी

एक तरह से कक्षाएं स्थिर प्रारंभिक उपयोग करने के लिए है … मुझे नहीं लगता कि ये विरासत में मिली हैं (यदि वे हैं तो यह काम नहीं करेगा):

 public class Dog extends Animal{ static { Animal a = new Dog(); //add a to the List } 

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

मैंने इस समस्या को बहुत सुंदर ढंग से पैकेज लेवल एनोटेशन का उपयोग करके हल किया और फिर उस टिप्पणी को एक तर्क के रूप में वर्गों की एक सूची बनाते हुए किया।

एक इंटरफ़ेस को लागू करने वाले जावा वर्गों को ढूंढें

कार्यान्वयन के लिए सिर्फ एक पैकेज-info.java बनाना होगा और उन वर्गों की सूची के साथ जादू की टिप्पणियां डालनी चाहिए, जिन्हें वे समर्थन देना चाहते हैं।