[英]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.