2011-10-19 12 views
5

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

List l = Reflection.getAllClasses(); 
String var; 
foreach(Class c : l) { 
    var = c.getField("fieldname"); 
    doSomething(var); 
} 

संपादित करें:

बस इसे स्पष्ट करना: कोड का निरीक्षण किया जार के भीतर से निष्पादित किया जाएगा।

+0

जब जार फ़ाइल में कक्षाओं की एक सूची शामिल नहीं है (उदाहरण के लिए 'गुण' फ़ाइल का उपयोग करना)? अंतिम लक्ष्य बताते हुए +1। –

+0

@AndrewThompson क्योंकि मैं इस प्रबंधन बोझ को सहन नहीं करना चाहता - हमेशा फाइलों की सूची याद रखना। – LordDoskias

+0

बिल्डिंग प्रक्रिया के हिस्से के रूप में सूची तैयार करने वाली कक्षा लिखना तुच्छ होगा। बिलकुल बोझ नहीं –

उत्तर

6

यह मेरे लिए काम कर देता है:

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Collection; 
import java.util.Enumeration; 
import java.util.jar.JarEntry; 
import java.util.jar.JarFile; 


public class ClassFinder 
{ 
    public static void main(String[] args) throws IOException 
    { 
    Collection<Class<?>> classes = new ArrayList<Class<?>>(); 

    JarFile jar = new JarFile("/home/nono/yamts/yamts.jar"); 
    for (Enumeration<JarEntry> entries = jar.entries() ; entries.hasMoreElements() ;) 
    { 
     JarEntry entry = entries.nextElement(); 
     String file = entry.getName(); 
     if (file.endsWith(".class")) 
     { 
      String classname = file.replace('/', '.').substring(0, file.length() - 6); 
      try 
      { 
       Class<?> c = Class.forName(classname); 
       classes.add(c); 
      } 
      catch (Throwable e) 
      { 
       System.out.println("WARNING: failed to instantiate " + classname + " from " + file); 
      } 
     } 
    } 

    for (Class<?> c : classes) 
     System.out.println(c); 
    } 
} 
+0

लेकिन यह बाहरी जार फ़ाइलों के लिए काम करेगा। क्या होगा यदि उपरोक्त कोड को उसी जार के साथ लक्ष्य के रूप में निष्पादित किया जा रहा है? संपादित करें: आपका कोड भी मेरे लिए काम नहीं करता है। प्रत्येक कक्षा के लिए मुझे "तत्काल विफल करने में विफल" – LordDoskias

+0

जब तक जार क्लासपाथ में है, तो आप कक्षा परिभाषा को पुनर्प्राप्त कर सकते हैं। यदि निर्दिष्ट जार क्लासपाथ में नहीं है, तो आपको शायद कस्टम क्लास लोडर के लिए अतिरिक्त काम निवेश करने की आवश्यकता होगी। – dagnelies

+0

पूरी तरह से काम किया, बहुत बहुत धन्यवाद – LordDoskias

1

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

हालांकि, यह JarInputStream का उपयोग करके किया जा सकता है।

+0

और जारफाइलस्ट्रीम के बिना, जारफाइल का उपयोग करके (स्वीकृत उत्तर दिखाता है) :) – Grodriguez

0

निम्नलिखित समाधान एक jar अपने classpath में या अपने classpath बाहर है कि साथ काम करेंगे।

try { 
     File pathToJar = new File("C:/some.jar"); 

     JarFile jarFile; 
      jarFile = new JarFile(pathToJar); 
     Enumeration<JarEntry> e = jarFile.entries(); 

     URL[] urls = { new URL("jar:file:" + pathToJar+"!/") }; 
     URLClassLoader cl = URLClassLoader.newInstance(urls); 

     while (e.hasMoreElements()) { 
      JarEntry je = e.nextElement(); 
      if(je.isDirectory() || !je.getName().endsWith(".class")){ 
       continue; 
      } 
      // -6 because of .class 
      String className = je.getName().substring(0,je.getName().length()-6); 
      className = className.replace('/', '.'); 
      System.out.println("Checking for class " + className); 
      Class c = cl.loadClass(className); 


      System.out.println("Class object " + c.getName()); 

     } 
    } catch (IOException | ClassNotFoundException e1) { 
     // TODO Auto-generated catch block 
     e1.printStackTrace(); 
    } 
संबंधित मुद्दे