gpt4 book ai didi

java - 使用反射从 Jar 文件中获取所有类

转载 作者:行者123 更新时间:2023-11-29 09:32:50 26 4
gpt4 key购买 nike

我需要从 ClassPath 上的 Jar 文件中获取所有类,我使用了 this article 我的解决方案。当我将路径设置为包名称时,本文中的方法有效,但如果包位于 Jar 文件中,则无效。

在评论下,人们发布了他们声称适用于 Jar 文件的代码(他们修改了文章代码)。我查看了他们的代码,它似乎应该可以工作,并且它确实适用于 在 jar 文件中的包,但他们没有指定传递什么作为参数告诉方法该包来自一个 jar 文件。我已经尝试了所有我能想到的组合,但没有任何效果。

因此,对于一个在 Jar 文件中的包,这将是使用这些方法的有效方式,

    Class[] myClasses = getClassesInPackage("my.package.name", null);

它应该与 Jar 文件中的包一起使用,但我不知道用什么替换 "my.package.name"。我试过只提供 Jar 文件中的包名称,但没有找到任何内容。

我的想法是它类似于 "myJarName""myJarName.my.package.name" 但这些都不起作用。

完整代码如下

    import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Member;
import java.net.URL;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.TreeSet;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static java.lang.System.out;

public class ClassSpy {

public static void main(String... args) {


try {

Class[] myClasses = getClassesInPackage("you.package.name.here", null);

for(Class index: myClasses)
out.format("Class:%n %s%n%n", index.getCanonicalName());

}
catch (ArrayIndexOutOfBoundsException e) {

e.printStackTrace();
}

/**
* Scans all classes accessible from the context
* class loader which belong to the given package
* and subpackages. Adapted from
* http://snippets.dzone.com/posts/show/4831
* and extended to support use of JAR files
* @param packageName The base package
* @param regexFilter an optional class name pattern.
* @return The classes
*/
public static Class[] getClassesInPackage(String packageName, String regexFilter) {

Pattern regex = null;

if (regexFilter != null)
regex = Pattern.compile(regexFilter);

try {

ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
assert classLoader != null;
String path = packageName.replace('.', '/');
Enumeration<URL> resources = classLoader.getResources(path);
List<String> dirs = new ArrayList<String>();

while (resources.hasMoreElements()) {

URL resource = resources.nextElement();
dirs.add(resource.getFile());
}

TreeSet<String> classes = new TreeSet<String>();
for (String directory : dirs) {

classes.addAll(findClasses(directory, packageName, regex));
}

ArrayList classList = new ArrayList();

for (String clazz : classes) {

classList.add(Class.forName(clazz));
}

return (Class[]) classList.toArray(new Class[classes.size()]);
}
catch (Exception e) {

e.printStackTrace();
return null;
}

}

/**
* Recursive method used to find all classes in a given path
* (directory or zip file url). Directories are searched recursively.
* (zip files are Adapted from http://snippets.dzone.com/posts/show/4831
* and extended to support use of JAR files @param path The base
* directory or url from which to search. @param packageName The package
* name for classes found inside the base directory @param regex an
* optional class name pattern. e.g. .*Test*
* @return The classes
*/
private static TreeSet findClasses(String path, String packageName, Pattern regex) throws Exception {

TreeSet classes = new TreeSet();

if (path.startsWith("file:") && path.contains("!")) {

String[] split = path.split("!");
URL jar = new URL(split[0]);

ZipInputStream zip = new ZipInputStream(jar.openStream());
ZipEntry entry;

while ((entry = zip.getNextEntry()) != null) {

System.out.println("Here 1");

if (entry.getName().endsWith(".class")) {

System.out.println("Here 2");

String className = entry.getName()
.replaceAll("[$].*", "")
.replaceAll("[.]class", "")
.replace('/', '.');

if (className.startsWith(packageName) && (regex == null
|| regex.matcher(className).matches()))

classes.add(className);
}

}

}

File dir = new File(path);

if (!dir.exists()) {

return classes;
}

File[] files = dir.listFiles();

for (File file : files) {

if (file.isDirectory()) {

assert !file.getName().contains(".");
classes.addAll(findClasses(file.getAbsolutePath()
, packageName + "." + file.getName()
, regex));
}
else if (file.getName().endsWith(".class")) {

String className = packageName + '.' + file
.getName()
.substring(0, file.getName().length() - 6);

if (regex == null || regex.matcher(className).matches())
classes.add(className);
}

}

return classes;
}

}

你应该能够复制所有代码并编译它(一些导入不会被使用,因为我只展示与问题相关的部分而不是整个程序)。

对于工作演示,您可以将 "my.package.name" 更改为类路径上的某个包。

最佳答案

Class[] myClasses = getClassesInPackage("my.package.name", null);

我以前从未使用过这种方法,如果我需要做你想做的事情,我会使用

Classname name = new Classname();

关于java - 使用反射从 Jar 文件中获取所有类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24900937/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com