【问题标题】:How can I get all Class files in a specific package in Java?如何在 Java 中获取特定包中的所有 Class 文件?
【发布时间】:2015-04-25 00:39:00
【问题描述】:

正如描述所说:如何获取给定包名的所有 Java 类文件的列表。

【问题讨论】:

  • 这不是问题。也许您应该将问题编辑为适当的问题并将答案作为答案发布。
  • 我知道。我在问答功能上遇到了一些问题。我只想分享那个代码 sn-p 因为这个社区帮助我解决了这个问题......

标签: java reflection methods package


【解决方案1】:

我在 SO 和其他网站上看到了许多问题和方法来查找特定 Java 包中的所有类。大多数解决方案对我不起作用。有时他们在 Jar 文件上工作,而不是在文件夹中的“普通”Java 项目上(就像 IDE 那样)或其他方式。因此,我将所有这些代码 sn-ps 放在一起并形成了一个解决方案,无论代码是在 Jar 文件中还是在普通文件夹结构中,它都可以(对我而言)开箱即用。

这真的很简单:你给方法getClassesInPackage 提供要检查的包的名称,你会得到这个包中所有类的列表。目前无一例外都是有序“消费”的。

玩得开心!这是代码:

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;
}

【讨论】:

  • 为什么会出现口袋妖怪异常?
  • 抛出异常的地方应该根据代码的使用情况插入自己的代码。仅在单个实例化错误时退出整个探索可能并不总是足够的。可以输出调试消息或做其他有用的事情。
  • 谢谢,它可以工作,即使它会扫描整个类路径(这可能需要一些时间)。幸运的是,我只将这段代码用于测试,所以没什么大不了的。
  • 在 Windows 上,如果 jar 中的类路径条目,我必须更改“路径”字符串变量中的分隔符:它应该始终是正斜杠,而不是当前代码建议的反斜杠适用于 Windows 平台。
  • 如何更改它以支持嵌套包?
【解决方案2】:

这是@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()
            }
        }
}

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 2014-02-11
    • 2014-01-05
    • 1970-01-01
    • 2020-06-28
    • 1970-01-01
    相关资源
    最近更新 更多