在java中检测具有特定注释的所有类

问题描述 投票:1回答:2

我正在制作一个应用程序来运行具有@Window注释的类中的所有方法,但是现在我已经得到了这个:

    Class<App> obj = App.class;
    Object t = null;
    try {
        t = obj.newInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }

    if (obj.isAnnotationPresent(Window.class)) {
        for (Method method : obj.getMethods()) {
            if (method.isAnnotationPresent(Window.Run.class)) {
                try {
                    method.invoke(t, new Object[] {});
                } catch (Exception e) {
                    System.err.println(e.getMessage());
                }
            }

        }

    }

但只有我知道班级名称才有效。如何在没有外部API的情况下检测项目中的所有类?

java
2个回答
0
投票

所以是的,这很困难,但我没有任何API

private static List<Class<?>> findClasses(File directory, String packageName) {
    List<Class<?>> classes = new ArrayList<Class<?>>();
    if (!directory.exists())
        return classes;

    File[] files = directory.listFiles();
    for (File file : files) {
        if (file.isDirectory()) {
            assert !file.getName().contains(".");
            classes.addAll(findClasses(file,
                    (!packageName.equals("") ? packageName + "." : packageName) + file.getName()));
        } else if (file.getName().endsWith(".class"))
            try {
                classes.add(Class
                        .forName(packageName + '.' + file.getName().substring(0, file.getName().length() - 6)));
            } catch (ClassNotFoundException e) {
                System.err.println(e.getMessage());
            }
    }
    return classes;
}

这将返回包中的所有类,如CMD中的TREE命令(如果您插入“”作为包装名称,这将返回项目中的所有类)。

public static Class<?>[] getClasses(String packageName) {

    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    assert classLoader != null;
    String path = packageName.replace('.', '/');
    Enumeration<URL> resources = null;
    try {
        resources = classLoader.getResources(path);
    } catch (IOException e) {
        System.err.println(e.getMessage());
    }
    List<File> dirs = new ArrayList<File>();
    while (resources.hasMoreElements()) {
        URL resource = resources.nextElement();
        dirs.add(new File(resource.getFile()));
    }
    List<Class<?>> classes = new ArrayList<Class<?>>();
    for (File directory : dirs)
        classes.addAll(findClasses(directory, packageName));

    return classes.toArray(new Class[classes.size()]);

}

然后此方法使用findClasses()方法从包中提取所有类。


-1
投票

我认为有一种非常简单的方法可以做到这一点,或者实际上即使创建自己的自定义实现也是值得的。

我不明白为什么你不想使用外部依赖这样做。几个月前我遇到了同样的问题,我只是选择使用Reflections API来完成我的工作。你可以在这里查看更多信息:https://github.com/ronmamo/reflections

除此之外,您可以考虑创建一个实用程序,它将扫描项目的各个包,查找使用该注释注释的类和方法,但如前所述,这将引导您创建与上面提到的库非常相似的内容。

除此之外,您可能会查看注释后处理器(即创建自己的),但我还没有尝试过这种方法,也不能告诉您是否符合您的要求。

最重要的是,除非有非常非常严格的需求要求您不能使用第三方库,否则我认为没有任何理由可能需要您重新发明轮子。

© www.soinside.com 2019 - 2024. All rights reserved.