[英]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>
可以將值作為A
或B
。
假設你不能改變你的類的任何東西,你就剩下反思了。 用反射來做的代碼如下:
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.