在运行时查找包中的所有类(并调用静态方法) [英] Find all classes in package (& call static methods) at runtime

查看:127
本文介绍了在运行时查找包中的所有类(并调用静态方法)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含很多类的程序包,这些类都有一个名为onLoad的静态方法.我想在程序启动时调用onLoad方法,但是我不想硬连接每一根,即classA.onLoad(); classB.onLoad();

I have a package in which there are many classes, and these classes all have a static method called onLoad. I want to call the onLoad method when the program starts, however I do not want to hard-wire each and every one, i.e. classA.onLoad(); classB.onLoad(); etc.

如何列出软件包com.foo.bar.asd中的所有类,并对它们全部运行onLoad()?

How can I list all classes in package com.foo.bar.asd and run onLoad() on all of them?

预先感谢

推荐答案

我发现这个问题很有趣,因此提出了一个解决方案.这里最棘手的部分是实际上找到给定程序包中的所有类.

I found this question quite interesting so I came up with a solution. The tricky part here is to actually find all classes that are in a given package.

在此示例中,我假设所有类都位于与类C相同的包中,并且除C之外的所有其他类均具有可能无法访问的onLoad方法(即private).然后,您可以使用以下示例代码.

In this example I assume that all classes are in the same package where the class C is and that all classes except C have an onLoad method which may be inaccessible (i.e. private). Then you can use the following example code.

public final class C {

    public static void main(String[] args) throws Exception {
        for (Class<?> cls : getClasses(C.class)) {
            if (cls != C.class) {
                Method onLoad = cls.getDeclaredMethod("onLoad");
                onLoad.setAccessible(true);
                onLoad.invoke(null);
            }
        }
    }

    private static List<Class<?>> getClasses(Class<?> caller)
            throws IOException, URISyntaxException {
        return Files.walk(getPackagePath(caller))
                .filter(Files::isRegularFile)
                .filter(file -> file.toString().endsWith(".class"))
                .map(path -> mapPathToClass(path, caller.getPackage().getName()))
                .collect(Collectors.toList());
    }

    private static Class<?> mapPathToClass(Path clsPath, String packageName) {
        String className = clsPath.toFile().getName();
        className = className.substring(0, className.length() - 6);
        return loadClass(packageName + "." + className);
    }

    private static Path getPackagePath(Class<?> caller)
            throws IOException, URISyntaxException {
        String packageName = createPackageName(caller);
        Enumeration<URL> resources = caller.getClassLoader()
                .getResources(packageName);
        return Paths.get(resources.nextElement().toURI());
    }

    private static String createPackageName(Class<?> caller) {
        return caller.getPackage().getName().replace(".", "/");
    }

    private static Class<?> loadClass(String name) {
        try {
            return Class.forName(name);
        } catch (ClassNotFoundException e) {
            return null;
        }
    }
}

我已经省略了所有异常检查,像resources.nextElement()这样的语句甚至可能引发异常.因此,如果您想解决这些情况,则需要在此处和此处添加一些检查.

I've omitted all exception checking and statements like resources.nextElement() may even throw an exception. So if you want to cover those cases, you need to add a few checks here and there.

这篇关于在运行时查找包中的所有类(并调用静态方法)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆