Java 反射:如何根据发送的对象调用动态方法

Java 反射:如何根据发送的对象调用动态方法,java,reflection,Java,Reflection,我试图在两个不同类的实例上调用方法。我想我想用反射来做这件事,但我遇到了麻烦。以下是我的无反射代码: public static void main(String[] args) throws IOException { Searcher search = new Searcher(); String folderToSearch = search.filepath; File folder = new File(folderToSearch); Set<

我试图在两个不同类的实例上调用方法。我想我想用反射来做这件事,但我遇到了麻烦。以下是我的无反射代码:

public static void main(String[] args) throws IOException {

    Searcher search = new Searcher();

    String folderToSearch = search.filepath;
    File folder = new File(folderToSearch);
    Set<File> list = new HashSet<File>();

    search.getFiles(folder, list);
    for (File file : list) {
        BruteForceSearch bSearch = new BruteForceSearch(file, toSearch);
        DisplaySearch(toSearch, bSearch);
    }

    System.out.println("\RegEx Search");

    for (File file : list) {
        RegExSearch rSearch = new RegExSearch(file, toSearch);
        DisplaySearch(toSearch, rSearch);
    }
}

private static void DisplaySearch(String toSearch, Object bSearch) {

    int count = 0;

    if (bSearch instanceof BruteForceSearch) {
        BruteForceSearch search = (BruteForceSearch) bSearch;     
    } else if (bSearch instanceof RegExSearch) {
        RegExSearch search = (RegExSearch) bSearch;     
    }

    if ( search.getCount(toSearch) > 0) {
        System.out.printf("%s - %s matches.%n", search.getFile(),
              search.getCount(toSearch));
        count++;
    }
    if (count == 0) {
        System.out.printf("Empty Result Set");
    }
}
publicstaticvoidmain(字符串[]args)引发IOException{
搜索者搜索=新搜索者();
字符串folderToSearch=search.filepath;
文件夹=新文件(folderToSearch);
Set list=新的HashSet();
search.getFiles(文件夹、列表);
用于(文件:列表){
BruteForceSearch bSearch=新的BruteForceSearch(文件,toSearch);
显示搜索(toSearch,bSearch);
}
System.out.println(“\RegEx Search”);
用于(文件:列表){
RegExSearch rSearch=新的RegExSearch(文件,toSearch);
显示搜索(toSearch、rSearch);
}
}
私有静态void DisplaySearch(字符串到搜索,对象b搜索){
整数计数=0;
if(b BruteForceSearch的搜索实例){
BruteForceSearch=(BruteForceSearch)b搜索;
}else if(b RegExSearch的搜索实例){
RegExSearch search=(RegExSearch)b搜索;
}
if(search.getCount(toSearch)>0){
System.out.printf(“%s-%s”匹配。%n),search.getFile(),
search.getCount(toSearch));
计数++;
}
如果(计数=0){
System.out.printf(“空结果集”);
}
}

我在
DisplaySearch()
方法中遇到问题。我如何在这里使用反射?还是应该编写不同的方法?

据我所知,您需要执行不同的代码,这取决于某些方法参数的动态类型。基本上有三种方法可以实现这一点:

  • instanceof运算符:您现在正在使用它,对于此设置,它实际上没有任何问题
  • 反射:obj.getClass()将为您提供对象的类,然后您可以获取类的名称(getName())或检查它是否是其他类的子类型(isAssignableFrom())。最后一个与instanceof基本相同,但有时可能更快,因为它不需要空检查。查看Javadocs以了解更多详细信息
  • 你可以使用

不能使用重载方法,因为Java根据参数的静态类型而不是动态类型选择适当的方法。只有在您知道呼叫站点的类型时,才能使用该选项。从您的代码示例中我不能完全确定,但我想您可能不知道。

如果
否则
代码块中可以调用搜索特定方法:

if (bSearch instanceof BruteForceSearch) {
    BruteForceSearch search = (BruteForceSearch) bSearch;     
} else if (bSearch instanceof RegExSearch) {
    RegExSearch search = (RegExSearch) bSearch;     
}
应该是:

if (bSearch instanceof BruteForceSearch) {
    BruteForceSearch search = (BruteForceSearch) bSearch;
    // perform brute force specific calls, e.g. search.setMaxTimeSeconds(100);
} else if (bSearch instanceof RegExSearch) {
    RegExSearch search = (RegExSearch) bSearch;
    // perform regular expression specific calls
}
当前,您正在强制转换到特定的搜索器类,将其分配给一个局部变量
search
(其中包含一个引用),然后丢弃该变量和引用,只剩下
bSearch


如果您只想对对象调用
search
,那么您需要创建一个接口或抽象类
search
,并让
BruteForceSearch
RegExSearch
实现(
implements
用于接口)或扩展(
extends
用于类)。这可能是您需要做的

然后,您的方法声明将是:

private static void displaySearch(String toSearch, Searcher searcher) {
    ...
    searcher.search(...);
    ...
}
请注意,我将该方法更改为以小写字符开头



这里不需要显式反射。

您在
DisplaySearch
方法中有什么?您的代码无法编译,
search
超出了范围。我添加了DisplaySearch方法,它只打印结果,但不打印结果。它根本不跑。正如@MaartenBodewes所指出的,它不会编译。