2011-10-19 28 views
5

我有一个包含30个左右类的jar文件。我想要的是,在主方法的开始处,我从该jar中调用一个类,该类使用Java的反射功能获取对jar中每个类的引用。我的最终目标是执行某种操作,查询为每个类定义的变量。基本上我正在寻找类似的东西。有没有一种简单的方法可以使用标准的反射API来完成此工作,或者制作工作解决方案会带来太多的麻烦?如何获取罐子中每个类的Class对象

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

编辑:

只是要清楚:该代码将从withing被检查罐子被执行。

+0

为什么在制作Jar文件时不包含一个列表(例如,使用'Properties'文件)类? +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

但这将工作的外部jar文件。如果上述代码将与目标相同的jar执行,该怎么办?编辑:您的代码也不适合我。对于每一个我得到“无法实例化”的类 – LordDoskias

+0

只要该jar在类路径中,就可以检索类定义。如果指定的jar不在类路径中,那么您可能需要为定制类加载器投入额外的工作。 – dagnelies

+0

工作完美,非常感谢 – LordDoskias

1

列出JAR文件中的所有类不能用反射来完成。

但是,它可以使用JarInputStream完成。

+0

而且还没有JarInputStream,通过使用JarFile(作为接受的答案演示):) – 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(); 
    } 
相关问题