我有一个包含30个左右类的jar文件。我想要的是,在main方法的开头,我从这个jar中调用一个类,使用Java的反射功能获取Class
对jar中每个类的引用。我的最终目标是执行某种操作,查询为每个类定义的变量。基本上我在寻找类似的东西。有没有一种简单的方法可以使用标准的反射API来做到这一点,或者制作一个有效的解决方案会有太多的麻烦?
List l = Reflection.getAllClasses();
String var;
foreach(Class c : l) {
var = c.getField("fieldname");
doSomething(var);
}
编辑:
只是说清楚:代码将从检查过的jar中执行。
答案 0 :(得分:7)
这对我有用:
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 :(得分:1)
列出JAR文件中的所有类不能用反射来完成。
但是,可以使用JarInputStream
。
答案 2 :(得分: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();
}