簡體   English   中英

如何使用枚舉避免反射

[英]How to avoid reflection using enums

我最近問了一個關於我的一些代碼的問題,我在那里使用了反射,一個想幫助我解決這個問題的人提到我不應該使用這樣的反射,並且有更好的方法。

所以我有一個用於在外部系統中搜索的界面:

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來回答。 Enum看起來像這樣:

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()。

所以這里的其他用戶說有可能將接口實現到枚舉中,然后我就不必反思了。 任何人都可以告訴我如何,因為我不知道,我不知道在哪里或搜索什么。 謝謝

似乎所有搜索引擎都有一個共同的方法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);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM