簡體   English   中英

使用反射代替長 switch 語句

[英]Using reflection instead of a long switch statement

嘿,所以我有一個很長的 switch 語句,它調用基於這樣的字符串的方法

private void callMethod(String name) {
    switch(name) {
        case "blah":
            blah();
            break;
        case "method":
            method()
            break;
    }
}

等等。

所以我用反射來縮短代碼

try {
    Method method = ClassName.class.getDeclaredMethod(name, args);
    method.invoke(args);
} catch (NoSuchMethodException e) {
    // switch default
}

只是想知道像這樣使用反射對內存/性能是否不利。 我只是經常調用這個函數。

編輯:我使用它的原因是因為用戶可以根據他們輸入的字符串選擇啟動游戲的不同部分。啟動事件的每個方法都以他們需要輸入的內容命名。

像這樣使用反射是一個壞主意。 在這里查看有關缺點的信息。

關於表現:

“由於反射涉及動態解析的類型,因此無法執行某些 Java 虛擬機優化。因此,反射操作的性能比非反射操作慢,應避免在對性能敏感的代碼段中頻繁調用應用程序。”

不要將反射視為StringArrayList類的普通工具,而應嘗試實現更適合您需求的軟件設計。 那么你將不得不很少考慮反思。


編輯:

性能下降當然值得商榷,但請注意其他缺點。 正如其他人已經指出的那樣,存在安全問題,例如,當用戶“調用”一個不打算由用戶直接“調用”的方法時。 另一個缺點是您的代碼中可能存在由於反射而在編譯時無法找到的問題。 還有更多的缺點......

在我看來,反射應該主要用於解決與生產代碼沒有直接關系的技術問題,例如在您的軟件測試中。

反思通常是最糟糕的做事方式。 它很慢,無法在運行時優化,並且編譯器無法標記錯誤。 正如 kpie 所指出的,讓用戶輸入直接控制執行哪個方法是一個安全漏洞。

任何長的switch語句都可以用 Map 替換。 在您的情況下, Map<String, Runnable>就足夠了:

Map<String, Runnable> actions = new HashMap<>();
actions.put("blah", this::blah);
actions.put("method", this::method);

// ...

Runnable action = actions.get(name);
if (action == null) {
    throw new IllegalArgumentException("Invalid name: " + name);
}
action.run();

暫無
暫無

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

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