簡體   English   中英

常量字符串替換

[英]Constant string substitution

我有一類常量

public class Constants {
    private static final String A = "1";
    private static final String B = "2";
}

我有另一個類,它將常量的名稱作為函數參數並調用該常量。

public class SomeClas {
    void someMethod(String constantName) {
        callSomeOtherMethod(Constants.<constantName>)
    }
}

我該怎么做呢? 我的<constantName>可以將值作為AB

假設你不能改變你的類的任何東西,你就剩下反思了。 用反射來做的代碼如下:

void someMethod(String constantName) throws NoSuchFieldException, IllegalAccessException {
    Field fd = Constants.class.getDeclaredField(constantName);
    fd.setAccessible(true);
    String val = (String) fd.get(null);
    callSomeOtherMethod(val);
}

答案取決於您對類Constants 如果這超出了您的控制范圍並且您無法更改它,那么反思就是要走的路。 (見 marcinj 的回答

但是,如果您可以完全控制Constants那么我會考慮重構為enum (自 Java 5 起可用)。 這是否值得取決於此類在您的代碼庫中的嵌入程度。 有多少引用Constants地方必須改變? 這是其他應用程序使用的共享類嗎? 可能是這里的重構太麻煩了,只有你能決定。

為了幫助您做出決定,這里總結了為什么使用枚舉通常被認為更可取的原因,當然對於新的開發。 如果您決定不重構,那么下次您需要像這樣創建新常量時仍然值得一看。

反對使用反射的原因

  • 性能- 運行時反射比編譯的方法調用或屬性查找慢得多。 如果您的代碼很少被調用,那么您可能不會注意到它,但如果這是一個被多次調用的實用方法,那么它可能是一個潛在的瓶頸。
  • 覆蓋訪問修飾符- 私有范圍屬性應該只能從同一個類中訪問。 通過覆蓋它,您可以在重構時引入問題,因為您的反射代碼可能依賴於它不應該知道的屬性或方法。
  • 編譯時安全- 如果您以標准方式調用方法或引用屬性,編譯器將檢查它是否存在。 如果您使用反射進行查找,那么您將面臨運行時錯誤。

比 String/int 常量更喜歡 enum 的原因
-每個常量都可以有屬性和方法- 使用 Joshua Bloch 示例,您可能有一個常量類,列出了太陽系的行星。 如果您使用枚舉類型,那么您可以添加質量、半徑等屬性以及檢索它們的方法。
-編譯時類型安全- 使用一類字符串常量,如果要將其傳遞給方法,則類型將是字符串,而不是常量。 這意味着編譯器會對您傳入的任何舊字符串感到滿意,無論它是否為常量。 如果您使用枚舉,則您具有編譯器可以檢查的正確類型。
-您可以免費獲得很多東西,例如 name()、valueOf()、實現 Serializable、Comparable 等。這意味着您不必重新發明輪子。
-這是一個深思熟慮的設計- 在枚舉之前,有許多設計模式可以通過不同級別的考慮來實現相同的目標。 例如,您是否擔心線程安全? 還是序列化? 如果您使用枚舉,則不必擔心這一點。

代碼示例
如果您確實決定重構為枚舉,那么這里有一個示例代碼片段來展示如何實現這一點。

public enum Constant
{
    A("1"),
    B("2");

    private String value;

    private Constant(String value)
    {
        this.value = value;
    }

    public Constant lookupConstantByValue(String value)
    {
        for(Constant constant : values())
        {
            if(constant.value.equals(value))
            {
                return constant;
            }
        }
        return null;
    }
}

您現在可以通過 A、B 名稱或“1”、“2”值查找常量值。 例如

public class SomeClas 
{
    void someMethod(String constantName) 
    {
        // if constantName is 1 or 2
        callSomeOtherMethod(Constant.lookupConstantByValue(constantName));
        // if constantName is A or B
        callSomeOtherMethod(Constant.valueOf(constantName));
    }
}

暫無
暫無

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

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