我最近问了一个关于我的代码的问题,我在其中使用了反射,一个想帮助我解决这个问题的人提到我不应该这样使用反射,并且有更好的方法来做。
所以我有一个用于在外部系统中搜索的接口:
public interface ReferenceController {
public Map<String, ReferenceElement> searchElements(String searchField, List<String> searchItems, SystemStage systemStage) throws Exception;
public String getStateMapping(String value);
public Boolean isAvailable(SystemStage systemStage) throws Exception;
}
我有一个ENUM,其中声明了我拥有的外部系统以及使用该接口的类的命名方式。因此,如果任何其他程序员想要实现一个新的外部系统,他只需填充接口并将两个值放入此ENUM和tada中即可。
所以我使用反射的部分是
public static void performSingleSearch(ReferenceSystem referenceSystem, String searchField, List<String> searchValues, SystemStage systemStage) throws Exception {
if(!isAvailable(referenceSystem, systemStage)) return;
Map<String, ReferenceElement> result = new HashMap<>();
try {
Class<?> classTemp = Class.forName(referenceSystem.getClassname());
Method method = classTemp.getMethod("searchElements", String.class , List.class, SystemStage.class);
result = (Map<String, ReferenceElement>) method.invoke(classTemp.newInstance(), searchField, searchValues, systemStage);
} catch (Exception e) {
return;
}
if(result != null) orderResults(result, referenceSystem);
}
在ENUM中,有一个函数getClassname,它用fqcn回答。 枚举看起来像这样:
public enum ReferenceSystem {
UCMDB (refSystems.ucmdb.UcmdbFunctions.class),
PROIPS (refSystems.proips.ProIPSFunctions.class),
KV (refSystems.kv.KvFunctions.class),
FISERVICE(refSystems.fiservice.FiServiceFunctions.class),
COMMAND (refSystems.command.CommandFunctions.class),
FII (refSystems.fii.FiiFunctions.class);
private Class<?> clazz;
private ReferenceSystem(Class<?> controllerClass) {
this.clazz = controllerClass;
}
public String displayName() {
ResourceBundle bundle = ResourceBundle.getBundle("EnumI18n", Locale.GERMAN);
return bundle.getString(toString());
}
public String localizedDisplayName(Locale locale) {
ResourceBundle bundle = ResourceBundle.getBundle("EnumI18n", locale);
return bundle.getString(toString());
}
public Class<?> getClassname() { return clazz; }
}
我已经根据@jhamon的回答对其进行了更改。
但是尝试时会出现错误
classTemp.newInstance().searchElemets(...)
因为它不了解searchElemts()。
所以这里的另一个用户说有可能将接口实现到枚举中,然后我就不必反思了。 谁能告诉我怎么做,因为我不知道,也不知道在哪里搜索。 谢谢
答案 0 :(得分:0)
似乎所有搜索引擎都有一个通用的方法searchElements
,它是在界面中定义的
知道这一点,为什么不直接调用此方法,而不要先查找该方法呢? ->无需再寻找方法。
public interface ReferenceController {
public Map<String, ReferenceElement> searchElements(String searchField, List<String> searchItems, SystemStage systemStage) throws Exception;
public String getStateMapping(String value);
public Boolean isAvailable(SystemStage systemStage) throws Exception;
}
不是将类名以String形式存储在Enum中,而是将.class->存储为不再需要查找类的反射。
public static void performSingleSearch(ReferenceSystem referenceSystem, String searchField, List<String> searchValues, SystemStage systemStage) throws Exception {
if(!isAvailable(referenceSystem, systemStage)) return;
Map<String, ReferenceElement> result = new HashMap<>();
try {
Class<?> classTemp = referenceSystem.getClazz();
result = ((ReferenceController) classTemp.newInstance()).searchElements(searchField, searchValues, systemStage);
} catch (Exception e) {
return;
}
if(result != null) orderResults(result, referenceSystem);
}