如何获取 Java 中特定包中的所有 Class 文件?
How can I get all Class files in a specific package in Java?
如描述所述:如何获取给定包名称的所有 Java class 文件的列表。
我在 SO 和其他网站上看到了很多问题和方法,可以在特定的 Java 包中找到所有 类。大多数解决方案对我都不起作用。有时他们处理 Jar 文件而不处理文件夹中的 "plain" Java 项目(就像 IDE 那样)或相反。所以我将所有这些代码片段放在一起并形成了一个解决方案,无论代码是在 Jar 文件中还是在普通文件夹结构中,它(对我来说)都可以开箱即用。
真的很简单:你给方法 getClassesInPackage
指定要检查的包的名称,你将得到这个包中所有 类 的列表。目前无一例外"consumed"井井有条。
玩得开心!这是代码:
public static final List<Class<?>> getClassesInPackage(String packageName) {
String path = packageName.replaceAll("\.", File.separator);
List<Class<?>> classes = new ArrayList<>();
String[] classPathEntries = System.getProperty("java.class.path").split(
System.getProperty("path.separator")
);
String name;
for (String classpathEntry : classPathEntries) {
if (classpathEntry.endsWith(".jar")) {
File jar = new File(classpathEntry);
try {
JarInputStream is = new JarInputStream(new FileInputStream(jar));
JarEntry entry;
while((entry = is.getNextJarEntry()) != null) {
name = entry.getName();
if (name.endsWith(".class")) {
if (name.contains(path) && name.endsWith(".class")) {
String classPath = name.substring(0, entry.getName().length() - 6);
classPath = classPath.replaceAll("[\|/]", ".");
classes.add(Class.forName(classPath));
}
}
}
} catch (Exception ex) {
// Silence is gold
}
} else {
try {
File base = new File(classpathEntry + File.separatorChar + path);
for (File file : base.listFiles()) {
name = file.getName();
if (name.endsWith(".class")) {
name = name.substring(0, name.length() - 6);
classes.add(Class.forName(packageName + "." + name));
}
}
} catch (Exception ex) {
// Silence is gold
}
}
}
return classes;
}
这是@mythbu 在 Kotlin 中的回答:
@Throws(Exception::class)
fun getClassesInPackage(packageName: String) = with(packageName.replace(".", File.separator)) {
System.getProperty("java.class.path")
.split(System.getProperty("path.separator").toRegex())
.flatMap { classpathEntry ->
if (classpathEntry.endsWith(".jar")) {
JarInputStream(FileInputStream(File(classpathEntry))).use { s ->
generateSequence { s.nextJarEntry }
.map { it.name }
.filter { this in it && it.endsWith(".class") }
.map { it.substring(0, it.length - 6) }
.map { it.replace('|', '.').replace('/', '.') }
.map { Class.forName(it) }
.toList()
}
} else {
File(classpathEntry, this).list()
?.asSequence()
?.filter { it.endsWith(".class") }
?.map { it.substring(0, it.length - 6) }
?.map { Class.forName("$packageName.$it") }
?.toList() ?: emptyList()
}
}
}
如描述所述:如何获取给定包名称的所有 Java class 文件的列表。
我在 SO 和其他网站上看到了很多问题和方法,可以在特定的 Java 包中找到所有 类。大多数解决方案对我都不起作用。有时他们处理 Jar 文件而不处理文件夹中的 "plain" Java 项目(就像 IDE 那样)或相反。所以我将所有这些代码片段放在一起并形成了一个解决方案,无论代码是在 Jar 文件中还是在普通文件夹结构中,它(对我来说)都可以开箱即用。
真的很简单:你给方法 getClassesInPackage
指定要检查的包的名称,你将得到这个包中所有 类 的列表。目前无一例外"consumed"井井有条。
玩得开心!这是代码:
public static final List<Class<?>> getClassesInPackage(String packageName) {
String path = packageName.replaceAll("\.", File.separator);
List<Class<?>> classes = new ArrayList<>();
String[] classPathEntries = System.getProperty("java.class.path").split(
System.getProperty("path.separator")
);
String name;
for (String classpathEntry : classPathEntries) {
if (classpathEntry.endsWith(".jar")) {
File jar = new File(classpathEntry);
try {
JarInputStream is = new JarInputStream(new FileInputStream(jar));
JarEntry entry;
while((entry = is.getNextJarEntry()) != null) {
name = entry.getName();
if (name.endsWith(".class")) {
if (name.contains(path) && name.endsWith(".class")) {
String classPath = name.substring(0, entry.getName().length() - 6);
classPath = classPath.replaceAll("[\|/]", ".");
classes.add(Class.forName(classPath));
}
}
}
} catch (Exception ex) {
// Silence is gold
}
} else {
try {
File base = new File(classpathEntry + File.separatorChar + path);
for (File file : base.listFiles()) {
name = file.getName();
if (name.endsWith(".class")) {
name = name.substring(0, name.length() - 6);
classes.add(Class.forName(packageName + "." + name));
}
}
} catch (Exception ex) {
// Silence is gold
}
}
}
return classes;
}
这是@mythbu 在 Kotlin 中的回答:
@Throws(Exception::class)
fun getClassesInPackage(packageName: String) = with(packageName.replace(".", File.separator)) {
System.getProperty("java.class.path")
.split(System.getProperty("path.separator").toRegex())
.flatMap { classpathEntry ->
if (classpathEntry.endsWith(".jar")) {
JarInputStream(FileInputStream(File(classpathEntry))).use { s ->
generateSequence { s.nextJarEntry }
.map { it.name }
.filter { this in it && it.endsWith(".class") }
.map { it.substring(0, it.length - 6) }
.map { it.replace('|', '.').replace('/', '.') }
.map { Class.forName(it) }
.toList()
}
} else {
File(classpathEntry, this).list()
?.asSequence()
?.filter { it.endsWith(".class") }
?.map { it.substring(0, it.length - 6) }
?.map { Class.forName("$packageName.$it") }
?.toList() ?: emptyList()
}
}
}