Java 如何为jar中的每个类获取类对象

Java 如何为jar中的每个类获取类对象,java,reflection,jar,introspection,Java,Reflection,Jar,Introspection,我有一个包含30个左右类的jar文件。我想要的是,在main方法的开头,我从这个jar中调用一个类,它使用Java的反射功能获得对jar中每个类的class引用。我的最终目标是执行某种操作,查询为每个类定义的变量。基本上我在找类似的东西。使用标准反射API有没有一种简单的方法来实现这一点,或者制定一个有效的解决方案会有太多的麻烦 List l = Reflection.getAllClasses(); String var; foreach(Class c : l) { var = c

我有一个包含30个左右类的jar文件。我想要的是,在main方法的开头,我从这个jar中调用一个类,它使用Java的反射功能获得对jar中每个类的
class
引用。我的最终目标是执行某种操作,查询为每个类定义的变量。基本上我在找类似的东西。使用标准反射API有没有一种简单的方法来实现这一点,或者制定一个有效的解决方案会有太多的麻烦

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


只是想明确一点:代码将从检查过的jar开始执行。

列出jar文件中的所有类不是通过反射可以完成的


但是,它可以使用。

这为我提供了窍门:

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);
    }
}
import java.io.IOException;
导入java.util.ArrayList;
导入java.util.Collection;
导入java.util.Enumeration;
导入java.util.jar.JarEntry;
导入java.util.jar.jar文件;
公共类查找器
{
公共静态void main(字符串[]args)引发IOException
{
收藏>();
JarFile jar=newjarfile(“/home/nono/yamts/yamts.jar”);
for(枚举条目=jar.entries();entries.hasMoreElements();)
{
JarEntry=entries.nextElement();
String file=entry.getName();
if(file.endsWith(“.class”))
{
字符串classname=file.replace('/','.').substring(0,file.length()-6);
尝试
{
类别c=类别forName(类别名称);
增加(c);
}
捕获(可丢弃的e)
{
System.out.println(“警告:未能从“+文件”实例化“+类名+”);
}
}
}
用于(c类:类)
系统输出打印ln(c);
}
}

以下解决方案将与
类路径中或
类路径之外的
jar
一起使用

 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();
    }
试试看{
File pathToJar=新文件(“C:/some.jar”);
JarFile-JarFile;
jarFile=新的jarFile(pathToJar);
枚举e=jarFile.entries();
URL[]URL={newurl(“jar:file:+pathToJar+”!/”};
URLClassLoader cl=URLClassLoader.newInstance(URL);
而(e.hasMoreElements()){
JarEntry je=e.nextElement();
if(je.isDirectory()| |!je.getName().endsWith(“.class”)){
继续;
}
//-6因为上课
字符串className=je.getName().substring(0,je.getName().length()-6);
className=className.replace(“/”,“.”);
System.out.println(“检查类”+类名);
c类=cl.loadClass(类名);
System.out.println(“类对象”+c.getName());
}
}捕获(IOException | ClassNotFoundException e1){
//TODO自动生成的捕捉块
e1.printStackTrace();
}

制作Jar文件时,为什么不在Jar文件中包含类的列表(例如,使用
属性
文件)+1声明最终目标。@AndrewThompson因为我不想承担这个管理负担-总是记住文件列表。编写一个类来准备列表作为构建过程的一部分是很简单的。一点负担也没有。@Lordoskias你有没有让这个运行在一个不在类路径上的jar上?你可以发布你的解决方案。但是这对外部jar文件有效。如果上述代码将使用与目标相同的jar执行,该怎么办?编辑:你的代码也不适合我。对于我得到的每个“实例化失败”的类,只要jar在类路径中,就可以检索类定义。如果指定的jar不在类路径中,那么您可能需要为自定义类加载器投入额外的工作。@dagnelies这段代码有效吗?我也继续无法实例化。。。异常java.lang.ClassNotFoundException:com…当我运行时,jar不在类路径上,而在classpath@ALM:不知道,是在2011年。也许从那时起,有些事情发生了轻微的变化。欢迎您调查并改进答案。从我上面的评论来看,jar显然必须在类路径中。@dagnelies NP我昨天发布后发现:)我将发布另一个答案。而且,在没有JarInputStream的情况下,使用JarFile(正如公认的答案所示):+1因为JarFile在本地文件系统上工作,而JarInputStream可以在不保存的情况下为远程JAR工作,例如,
newJarInputStream(newURL(“https://example.com/my.jar)…