Как я могу получить объект класса для каждого класса в банке - PullRequest
6 голосов
/ 19 октября 2011

У меня есть JAR-файл с 30 или около того классами. Я хочу, чтобы в начале основного метода я вызывал класс из этого jar, который, используя возможности отражения Java, получает Class ссылки на каждый класс в jar. Моя конечная цель - выполнить какую-то операцию, запрашивая переменную, определенную для каждого класса. В основном я ищу что-то вроде. Есть ли простой способ сделать это, используя стандартные API отражения, или это будет слишком хлопотно, чтобы сделать рабочее решение?

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

Edit:

Просто чтобы прояснить: код будет выполнен изнутри проверенной банки.

Ответы [ 3 ]

7 голосов
/ 19 октября 2011

Это помогает мне:

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);
    }
}
1 голос
/ 19 октября 2011

Перечисление всех классов в файле JAR - это не то, что можно сделать с помощью отражения.

Однако это можно сделать с помощью JarInputStream.

0 голосов
/ 26 мая 2016

Следующее решение будет работать с 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();
    }
...