दिलचस्प पोस्ट
पहले const या const के बाद? स्ट्रिंग से होस्टनाम नाम निकालें मेवेन के साथ फाइल कॉपी करने के लिए सर्वोत्तम प्रथाएं AsyncTask को कई बार निष्पादित करें x पेजर के jqgrid पेज 1 कैसे एक जावास्क्रिप्ट चर सेट करने के लिए? सी ++ में बाइनरी फ़ाइल को बहुत तेज़ी से लिखना एंड्रॉइड एपैंपपेट v7 21 लाइब्रेरी से ड्रॉवर एआररो टॉगल को कैसे कार्यान्वित करें JTable में एकाधिक पंक्ति चयन एएसपी.नेट एमवीसी जेएसनआरसल्ट तिथि प्रारूप JQuery के तत्व के लिए कक्षा सूची प्राप्त करें संपत्ति (बिना अतिरिक्त प्रसंस्करण) बनाम सार्वजनिक क्षेत्र कैसे घटना पर jquery पर एक निर्देश अद्यतन एनजी मॉडल बनाने के लिए? SO_REUSEADDR (setockopt विकल्प) का अर्थ क्या है – लिनक्स? Launch4j के साथ एक JRE बंडल करने के लिए कैसे?

मैं सभी वर्गों को पैकेज में कैसे गणना कर सकता हूं और उन्हें सूची में जोड़ सकता हूं?

मुझे एक पैकेज में सभी वर्गों की गणना करने और उन्हें एक सूची में जोड़ना होगा। एकल वर्ग के लिए गैर-गतिशील संस्करण इस तरह होता है:

List allClasses = new ArrayList(); allClasses.add(String.class); 

पैकेज और सभी उपपैकेजों में सभी वर्गों को जोड़ने के लिए मैं इसे गतिशील कैसे कर सकता हूं?


अद्यतन: प्रारंभिक उत्तर पढ़ने के बाद, यह बिल्कुल सही है कि मैं एक और माध्यमिक समस्या को हल करने की कोशिश कर रहा हूं, तो मुझे यह बताना चाहिए। और मुझे पता है कि यह संभव है क्योंकि अन्य उपकरण ऐसा करते हैं। नया प्रश्न यहाँ देखें

अद्यतन: इसे फिर से पढ़ना, मैं देख सकता हूं कि यह कैसे भूल गया है। मैं संकलन के बाद फ़ाइल सिस्टम से मेरी सभी परियोजना की कक्षाओं की गणना करना चाहता हूं।

वेब के समाधान से एकत्रित समाधान "मैं सभी वर्गों को पैकेज में कैसे गणना कर सकता हूं और उन्हें सूची में जोड़ सकता हूं?"

**** अपडेट 1 (2012) ****

ठीक है, मैं अंत में कोड स्निपेट को साफ करने के लिए नीचे मिल गया है I मैंने इसे अपनी गिथूब प्रोजेक्ट में फंस गया और यहां तक ​​कि परीक्षण भी जोड़े।

https://github.com/ddopson/java-class-enumerator

**** अपडेट 2 (2016) ****

एक और अधिक मजबूत और सुविधा युक्त क्लासपाथ स्कैनर के लिए, https://github.com/lukehutch/fast-classpath-scanner/wiki देखें । मैं पहले उच्च स्तरीय समझ हासिल करने के लिए अपना कोड स्निपेट पढ़ना चाहता हूं, फिर उत्पादन उद्देश्यों के लिए लुकहूह के उपकरण का उपयोग करना

**** मूल पोस्ट (2010) ****

कड़ाई से बोलते हुए, पैकेज में वर्गों को सूचीबद्ध करना संभव नहीं है। यह इसलिए है क्योंकि पैकेज वास्तव में एक नेमस्पेस (उदाहरण के लिए com.epicapplications.foo.bar) से ज्यादा कुछ नहीं है, और क्लासपाथ में किसी भी जार फ़ाइल संभावित रूप से एक पैकेज में कक्षाएं जोड़ सकते हैं। इससे भी बदतर, क्लासलोडर मांग पर कक्षाएं लोड करेगा, और क्लासपाथ का हिस्सा नेटवर्क कनेक्शन के दूसरे पक्ष पर हो सकता है।

अधिक प्रतिबंधात्मक समस्या को हल करना संभव है। उदाहरण के लिए, एक JAR फ़ाइल में सभी कक्षाएं, या सभी वर्ग जो एक जेएआर फ़ाइल किसी विशेष पैकेज के अंदर परिभाषित करते हैं यह वैसे भी अधिक सामान्य परिदृश्य है

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

सादे-पुरानी-निर्देशिकाओं में कक्षा फ़ाइलों के लिए वेब पर कई नमूने हैं हम में से ज्यादातर इन दिनों जेआर फाइलों के साथ काम करते हैं

जेआर फाइलों के साथ काम करने के लिए, यह कोशिश करें …

 private static ArrayList<Class<?>> getClassesForPackage(Package pkg) { String pkgname = pkg.getName(); ArrayList<Class<?>> classes = new ArrayList<Class<?>>(); // Get a File object for the package File directory = null; String fullPath; String relPath = pkgname.replace('.', '/'); System.out.println("ClassDiscovery: Package: " + pkgname + " becomes Path:" + relPath); URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); System.out.println("ClassDiscovery: Resource = " + resource); if (resource == null) { throw new RuntimeException("No resource for " + relPath); } fullPath = resource.getFile(); System.out.println("ClassDiscovery: FullPath = " + resource); try { directory = new File(resource.toURI()); } catch (URISyntaxException e) { throw new RuntimeException(pkgname + " (" + resource + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...", e); } catch (IllegalArgumentException e) { directory = null; } System.out.println("ClassDiscovery: Directory = " + directory); if (directory != null && directory.exists()) { // Get the list of the files contained in the package String[] files = directory.list(); for (int i = 0; i < files.length; i++) { // we are only interested in .class files if (files[i].endsWith(".class")) { // removes the .class extension String className = pkgname + '.' + files[i].substring(0, files[i].length() - 6); System.out.println("ClassDiscovery: className = " + className); try { classes.add(Class.forName(className)); } catch (ClassNotFoundException e) { throw new RuntimeException("ClassNotFoundException loading " + className); } } } } else { try { String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); JarFile jarFile = new JarFile(jarPath); Enumeration<JarEntry> entries = jarFile.entries(); while(entries.hasMoreElements()) { JarEntry entry = entries.nextElement(); String entryName = entry.getName(); if(entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) { System.out.println("ClassDiscovery: JarEntry: " + entryName); String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); System.out.println("ClassDiscovery: className = " + className); try { classes.add(Class.forName(className)); } catch (ClassNotFoundException e) { throw new RuntimeException("ClassNotFoundException loading " + className); } } } } catch (IOException e) { throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e); } } return classes; } 

मुझे पता चला कि यह कैसे करना है यहां प्रक्रिया है:

  1. रूट पैकेज में एक वर्ग के साथ शुरू करें, और फ़ोल्डर को कक्षा लोडर से प्राप्त करें
  2. इस फ़ोल्डर में सभी। वर्ग फ़ाइलों को बार-बार गणना करें
  3. फ़ाइल नामों को पूरी तरह से योग्य वर्ग के नामों में कनवर्ट करें
  4. कक्षाएं प्राप्त करने के लिए कक्षा .forName () का उपयोग करें

यहां कुछ गंदे चालें हैं जो मुझे थोड़ा असहज बनाती हैं, लेकिन यह काम करता है – उदाहरण के लिए:

  1. स्ट्रिंग हेरफेर का उपयोग करके पैकेज नामों के पथ नाम परिवर्तित करना
  2. रूट उपसर्ग को अलग करना सक्षम करने के लिए रूट पैकेज नाम को हार्ड-कोडिंग करना

बहुत बुरा है कि स्टैक ओवरफ्लो मुझे अपना जवाब स्वीकार करने की अनुमति नहीं देता …

आप अपने पुस्तकालय FastClasspathScanner कोशिश कर सकते

पैकेज में सभी वर्गों की गणना करने के लिए, निम्न करें:

 Set<String> classNames = new FastClassPathScanner("com.mypackage") .scan() .getNamesOfAllClasses(); 

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

यह अजीब बात है कि यह प्रश्न हर बार एक समय में आता है। समस्या यह है कि यह कीवर्ड "नेमस्पेस" नाम का अधिक उपयुक्त होगा। जावा पैकेज किसी ठोस कंटेनर को चित्रित नहीं करता है जो किसी भी समय पैकेज में सभी वर्गों को रखता है। यह केवल एक टोकन को परिभाषित करता है कि कक्षाएं यह घोषणा करने के लिए उपयोग कर सकती हैं कि वे उस पैकेज के सदस्य हैं। पैकेज में सभी वर्गों को निर्धारित करने के लिए आपको संपूर्ण कक्षापथ (जैसा कि एक अन्य उत्तर दिया गया है) के माध्यम से खोजना होगा।

इसके लिए एक चेतावनी है: एपिनडेगिन / सर्वलेट कंटेनर जैसे टॉमकैट और जेबीस में श्रेणीबद्ध वर्ग लोडर हैं । सिस्टम वर्ग लोडर प्राप्त करना नहीं होगा।

टॉमकेट का काम (चीजें बदल सकती हैं, लेकिन मेरी वर्तमान अनुभव मुझे अन्यथा विश्वास नहीं करती है) परन्तु प्रत्येक एप्लिकेशन संदर्भ में यह खुद का क्लास लोडर है ताकि अनुप्रयोग 'foo' के लिए कक्षाएं 'fooV2' के लिए कक्षाओं से टकराने न हो '

बस एक उदाहरण के रूप में यदि सभी वर्गों को एक uber श्रेणी के संदर्भ में मिला दिया गया तो आपको नहीं पता होगा कि क्या आप संस्करण 1 या संस्करण 2 के लिए उपयुक्त कक्षाओं का उपयोग कर रहे थे।

इसके अतिरिक्त, प्रत्येक को सिस्टम क्लासेस जैसे java.lang.String के लिए एक्सेस की आवश्यकता होती है। यह पदानुक्रम है यह पहले स्थानीय ऐप संदर्भ की जांच करता है और इसे आगे बढ़ता है (यह मेरी वर्तमान स्थिति है BTW)।

इसे प्रबंधित करने के लिए, एक बेहतर दृष्टिकोण होगा: this.getClass ()। GetClassloader ()

मेरे मामले में मेरे पास एक webservice है जिसे कुछ मॉड्यूल पर स्व-खोज करने की आवश्यकता होती है और वे जाहिरा तौर पर 'इस' webservice संदर्भ या सिस्टम संदर्भ में रहते हैं। उपर्युक्त करने से मुझे दोनों को जांचना पड़ता है। बस सिस्टम क्लासलोडर प्राप्त करने से मुझे किसी भी अनुप्रयोग कक्षाओं तक पहुंच नहीं है (और इस तरह मेरे संसाधन शून्य हैं)

देखो क्या java.net.URLClassLoader कर रहा है यह वर्गों की गणना कभी नहीं करता है, यह केवल एक के लिए पूछे जाने पर कक्षाएं ढूँढ़ने की कोशिश करता है यदि आप कक्षाओं की गणना करना चाहते हैं, तो आपको क्लासपाथ प्राप्त करने की आवश्यकता होगी, इसे निर्देशिकाओं और जार फाइलों में विभाजित करें। डायरेक्टरी (और उनकी सबडिरेक्टरीज) और फाइल के लिए जार फाइलें स्कैन करें * * क्लास के साथ।

यह ओपन सोर्स परियोजनाओं को देखकर लायक हो सकता है जो आपको प्रेरणा के लिए गणना करना चाहते हैं (जैसे ग्रहण )।

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

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

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

दूसरी ओर, यदि वे सभी पैकेज में हैं तो आप क्या चाहते हैं, तो उस पैकेज में सभी वर्गों को दिए गए इंटरफ़ेस को लागू करें।