[英]Is Java Reflection bad practice?
Consider this piece of code:考虑这段代码:
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);
}
...
...
I'm using java reflection here to avoid an if construct.我在这里使用 java 反射来避免 if 构造。 The choicebox is used to let the user decide on what attribute he wants to search, there are 6 possibilities right now.
选择框用于让用户决定他要搜索的属性,目前有 6 种可能性。 I've gotten some comments from other students that using reflection is 'bad practice'.
我从其他学生那里得到了一些评论,认为使用反射是“不好的做法”。 Is this the case?
是这样吗? Why?
为什么?
There are many reasons this is bad practice. 造成这种情况的原因有很多。 Among them:
其中:
Consider instead populating your combo box with Consumer<String>
objects: 请考虑使用
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 ;
}
};
}
Then you just do: 那你就做:
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);
}
}
Yes, reflection is slow, and it creates fragile code when used in this way. 是的,反射很慢,并且在以这种方式使用时会产生脆弱的代码。
If you want to avoid the if statement, you should use polymorphism. 如果要避免使用if语句,则应使用多态。 Create an interface
Searcher
with public void search(String query)
, create implementations for every type of search you want to do, and then put an instance of each implementation as the value of a Map<String, Searcher>
, keyed by the value of the search choice box. 使用
public void search(String query)
创建一个接口Searcher
,为您想要执行的每种类型的搜索创建实现,然后将每个实现的实例作为Map<String, Searcher>
的值,键入值搜索选择框。
Because Java enums are objects, you could also use an enum as your map. 因为Java枚举是对象,所以您也可以使用枚举作为地图。 Each enum value would define their own
search(string)
implementation. 每个枚举值都将定义自己的
search(string)
实现。 You could then call the implementation you want using SearchEnumTypeName.valueOf(searchChoiceBox.getValue()).search(query)
然后,您可以使用
SearchEnumTypeName.valueOf(searchChoiceBox.getValue()).search(query)
调用所需的实现SearchEnumTypeName.valueOf(searchChoiceBox.getValue()).search(query)
If the world of Ahead of Time Compilation with GraalVM interests you (which is receiving more interest in the world of microservices), I can tell you that reflection is the biggest barrier.如果你对使用 GraalVM 的Ahead of Time Compilation世界感兴趣(这对微服务世界越来越感兴趣),我可以告诉你反射是最大的障碍。 And in my opinion it's unnecessary.
在我看来,这是不必要的。
You have to identify classes manually (via reflection.json) that the Java linker has to retain as it tries to reduce unused code bloating the binary.您必须手动(通过反射.json)识别 Java linker 必须保留的类,因为它试图减少未使用的代码使二进制文件膨胀。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.