Java 反射:在自定义 AbstractProcessor 中查找方法用法 [英] Java Reflection: Find method usage in custom AbstractProcessor

查看:59
本文介绍了Java 反射:在自定义 AbstractProcessor 中查找方法用法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是反思的新手.有什么方法可以检测调用特定方法的位置吗?例如:

I'm newbie in reflection. Is there any way to detect where is an specific method invoked? For example:

public class MyClass {

   public static void method(){ 
       //DO SOMETHING
   }

}

public class Test {

    public test(){
       MyClass.method();
    }

}

public class MyProcessor extends AbstractProcessor {

   public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {

      Method method = MyClass.class.getDeclaredMethod("method");

      Class classWhereMethodIsInvoked = obtainClassWhereMethodIsInvoked(method); 

   }

   public Class obtainClassWhereMethodIsInvoked(Method method) {
      //here I want to search one class that invoke that method, in this case Test.class
   }

}

这样的事情是可能的还是我快疯了?

is something like this possible or I am going crazy?

推荐答案

是的,如果你真的想要它,它是可行的.您可以使用 classLoader 搜索类路径并通过所有类文件扫描方法名称.下面是一个非常简单的例子来表明它是可行的.在下面的示例中,我发现了此类中使用的println"方法的用法.本质上,您可以将范围从我示例中的一个文件扩展到所有类文件.

Yes it doable if you really want it. You can use the classLoader to search through the class path and scan for the method name through all the class files. Below is a very simplistic example to show that it is doable. In the example below I find usage of the "println" method being used in this class. Essentially you can just broaden the scope from one file in my example to all the class files.

public class SearchClasses {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) throws FileNotFoundException {


//      InputStream is = SearchClasses.class.getClassLoader().getResourceAsStream("resources.SearchClasses.class");
        InputStream is = new FileInputStream(new File("build/classes/resources/SearchClasses.class"));

        boolean found = false;
        Scanner scanner = new Scanner(is);
        while (scanner.hasNext()) {
            if (scanner.nextLine().contains("println")) {
                System.out.print("println found");
                found = true;
                break;
            }
        }

        if (!found) {
                System.out.print("println NOT found");          
        }

    }

    public static void testMethod() {
        System.out.println("testing");
    }

}

在我的 IDE 中,我必须使用 FileInputStream 来访问我正在搜索的类文件......但是如果您正在搜索 jar 文件,那么您可以改用 classLoader.您将需要搜索所有类路径的机制……这并非不可能,但为了简洁起见,我将其保留了下来.

In my IDE I had to use the FileInputStream to access the class file I was searching in.... but if you are searching through jar files then you can use the classLoader instead. You would need mechanism to search through all of the class path... this is not impossible but I left it our for brevity.

这是尝试让它完全工作......在类路径中搜索您的方法的所有文件.

Here is an attempt to get it working completely.. searches all files in class path for your method.

public class SearchClasses {

    /**
     * @param args the command line arguments
     * @throws java.io.FileNotFoundException
     */
    public static void main(String[] args) throws FileNotFoundException, IOException {

        printAllFileWithMethod("println");
    }

    public static void printAllFileWithMethod(String methodName) throws FileNotFoundException, IOException {
        Enumeration<URL> roots = SearchClasses.class.getClassLoader().getResources("");

        List<File> allClassFiles = new ArrayList<>();
        while (roots.hasMoreElements()) {
            File root = new File(roots.nextElement().getPath());
            allClassFiles.addAll(getFilesInDirectoryWithSuffix(root, "class"));
        }

        for (File classFile : allClassFiles) {
            InputStream is = new FileInputStream(classFile);

            boolean found = false;
            Scanner scanner = new Scanner(is);
            while (scanner.hasNext()) {
                if (scanner.nextLine().contains(methodName)) {
                    System.out.print(methodName + " found in " + classFile.getName() + "\n");
                    found = true;
                    break;
                }
            }

        }
    }

    public static void testMethod() {
        System.out.println("testing");
    }

    static List<File> getFilesInDirectoryWithSuffix(File dir, String suffix) {
        List<File> foundFiles = new ArrayList<>();
        if (!dir.isDirectory()) {
            return foundFiles;
        }
        for (File file : dir.listFiles()) {
            if (file.isDirectory()) {
                foundFiles.addAll(getFilesInDirectoryWithSuffix(file, suffix));
            } else {
                String name = file.getName();
                if (name.endsWith(suffix)) {
                    foundFiles.add(file);
                }
            }

        }
        return foundFiles;
    }

}

这篇关于Java 反射:在自定义 AbstractProcessor 中查找方法用法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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