有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我正在制作一个应用程序,该应用程序运行具有@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的情况下,如何检测项目中的所有类


共 (2) 个答案

  1. # 1 楼答案

    是的,这很难,但我没有任何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()方法从包中提取所有类

  2. # 2 楼答案

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

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

    除此之外,您还可以考虑创建一个实用程序,该实用程序将扫描项目的各个包,寻找用该注释注释的类和方法,但正如前面提到的,这将导致您创建类似于上面提到的库的东西

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

    底线是,除非有一个非常非常严格的需求要求您不能使用第三方库,否则我看不出有任何理由要求您重新发明轮子