Java 反射是不好的做法吗?

wim*_*etr 7 java reflection javafx

考虑这段代码:

public void doSearch(ActionEvent event) {
    String query = searchTextField.getText();
    if (query.isEmpty()) {
        data = FXCollections.observableArrayList(dc.getJobCoachRepo().getList());
        usersTableView.setItems(data);
    } else {

        String searchOn = "search" + searchChoiceBox.getValue();
        try {
            Method m = this.getClass().getMethod(searchOn, String.class);
            m.invoke(this, query);
        } catch (Exception e) {

        }
    }
}

public void searchFirstName(String query) {
    data = FXCollections.observableArrayList(dc.getJobCoachRepo().searchFirstName(query));
    usersTableView.setItems(data);

}
...
...
Run Code Online (Sandbox Code Playgroud)

我在这里使用 java 反射来避免 if 构造。选择框用于让用户决定他要搜索什么属性,目前有 6 种可能性。我从其他学生那里得到了一些评论,认为使用反思是“不好的做法”。是这样吗?为什么?

Jam*_*s_D 10

这是不好的做法有很多原因。他们之中:

  1. 它不坚固。用户在文本字段中输入的文本必须与方法的名称相匹配,这意味着根本不应该相关的事物之间存在可怕的耦合程度
  2. 反射表现不佳。在这里可能没什么大不了的,但如果没有充分的理由使用反射,你就不应该使用。
  3. 使用 lambda 表达式有一个现成的更好的解决方案。

考虑用Consumer<String>对象填充组合框:

ComboBox<Consumer<String>> searchChoiceBox = new ComboBox<>();
searchChoiceBox.getItems().add(createSearchOption(this::searchFirstName, "First Name"));

// ...

private Consumer<String> createSearchOption(Consumer<String> search, String name) {
    return new Consumer<String>() {
        @Override
        public void accept(String s) {
            search.accept(s);
        }
        @Override
        public String toString() {
            return name ;
        }
    };
}
Run Code Online (Sandbox Code Playgroud)

然后你只需要做:

public void doSearch(ActionEvent event) {
    String query = searchTextField.getText();
    if (query.isEmpty()) {
        data = FXCollections.observableArrayList(dc.getJobCoachRepo().getList());
        usersTableView.setItems(data);
    } else {

        searchChoiceBox.getValue().accept(query);

    }
}
Run Code Online (Sandbox Code Playgroud)