[英]Constant string substitution
I have a class of constants我有一类常量
public class Constants {
private static final String A = "1";
private static final String B = "2";
}
I have another class which takes in the name of the constant as a function parameter and calls the constant.我有另一个类,它将常量的名称作为函数参数并调用该常量。
public class SomeClas {
void someMethod(String constantName) {
callSomeOtherMethod(Constants.<constantName>)
}
}
How Do i do this?我该怎么做呢? My
<constantName>
can take values as A
or B
.我的
<constantName>
可以将值作为A
或B
。
Assuming you cannot change anything in the way your classes look like, you are left with reflection.假设你不能改变你的类的任何东西,你就剩下反思了。 The code to do it with reflection is as follows:
用反射来做的代码如下:
void someMethod(String constantName) throws NoSuchFieldException, IllegalAccessException {
Field fd = Constants.class.getDeclaredField(constantName);
fd.setAccessible(true);
String val = (String) fd.get(null);
callSomeOtherMethod(val);
}
The answer depends on how much control you have of the class Constants
.答案取决于您对类
Constants
。 If this is out of your control and you cannot change it then reflection is the way to go.如果这超出了您的控制范围并且您无法更改它,那么反思就是要走的路。 (see marcinj's answer )
(见 marcinj 的回答)
However, if you have full control over Constants
then I would consider refactoring to an enum
(available since Java 5).但是,如果您可以完全控制
Constants
那么我会考虑重构为enum
(自 Java 5 起可用)。 Whether this is worthwhile will depend on how embedded this class is in your code base.这是否值得取决于此类在您的代码库中的嵌入程度。 How many places that reference
Constants
would have to change?有多少引用
Constants
地方必须改变? Is this a shared class used by other applications?这是其他应用程序使用的共享类吗? It could be that refactoring here is too much hassle, only you can decide.
可能是这里的重构太麻烦了,只有你能决定。
To help you decide here is a summary of reasons why using an enum would generally be considered preferable, certainly for new development.为了帮助您做出决定,这里总结了为什么使用枚举通常被认为更可取的原因,当然对于新的开发。 If you decide not to refactor then it's still worth a look for the next time you need to create new constants like this.
如果您决定不重构,那么下次您需要像这样创建新常量时仍然值得一看。
Reasons against using reflection反对使用反射的原因
Reasons to prefer an enum to String/int constants比 String/int 常量更喜欢 enum 的原因
- Each constant can have attributes and methods - Using the Joshua Bloch example you might have a constants class listing the planets of the solar system. -每个常量都可以有属性和方法- 使用 Joshua Bloch 示例,您可能有一个常量类,列出了太阳系的行星。 If you use an enum type then you can add attributes such as mass, radius etc and methods to retrieve them.
如果您使用枚举类型,那么您可以添加质量、半径等属性以及检索它们的方法。
- Compile time type safety - With a class of String constants if you want to pass this in to a method the type will be String, not Constants. -编译时类型安全- 使用一类字符串常量,如果要将其传递给方法,则类型将是字符串,而不是常量。 This means the compiler will be happy with any old String you pass in whether it's a Constant or not.
这意味着编译器会对您传入的任何旧字符串感到满意,无论它是否为常量。 If you use an enum you have a proper type that the compiler can check.
如果您使用枚举,则您具有编译器可以检查的正确类型。
- You get lots for free such as name(), valueOf(), implements Serializable, Comparable etc. This means you don't have to re-invent the wheel. -您可以免费获得很多东西,例如 name()、valueOf()、实现 Serializable、Comparable 等。这意味着您不必重新发明轮子。
- It's a thought out design - Before enums there were a number of design patterns to achieve the same thing with varying levels of considerations. -这是一个深思熟虑的设计- 在枚举之前,有许多设计模式可以通过不同级别的考虑来实现相同的目标。 For example do you worry about thread safety?
例如,您是否担心线程安全? Or Serialization?
还是序列化? If you use an enum you don't have to worry about this.
如果您使用枚举,则不必担心这一点。
Code example代码示例
If you do decide to refactor to an enum then here is an example code snippet to show how this might be achieved.如果您确实决定重构为枚举,那么这里有一个示例代码片段来展示如何实现这一点。
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;
}
}
You could now lookup constant values either by the A,B name or the "1", "2" value.您现在可以通过 A、B 名称或“1”、“2”值查找常量值。 eg
例如
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.