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

时间:2016-02-01 19:08:33

标签: java reflection

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

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");
    }
}

我在DisplaySearch()方法遇到问题。我怎样才能在这里使用反射?或者我应该写不同的方法?

2 个答案:

答案 0 :(得分:0)

据我了解,您希望执行不同的代码,具体取决于某些方法参数的动态类型。基本上有三种方法可以实现这一目标:

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

您不能使用重载方法,因为Java根据参数的静态类型选择适当的方法,而不是动态类型。如果您知道呼叫站点的类型,则只能使用它。我不完全确定你的代码示例,但我猜你不知道。

答案 1 :(得分:0)

您可以在ifelse代码块中调用特定于搜索的方法:

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(其中包含引用),然后抛弃变量和引用,只留下{ {1}}。

如果您只想在对象上调用bSearch,则需要创建一个接口或抽象类search,并让SearcherBruteForceSearch实现({{ 1}} for interfaces)或扩展(类RegExSearch)它。这可能是你需要做的。

您的方法声明将是:

implements

请注意,我将方法更改为以小写字符开头。

这里没有必要进行明确的反思。