通过反射初始化字符串常量

时间:2013-06-18 18:07:40

标签: java string reflection constants

我正在重构一些旧代码并找到一个包含字符串常量的类“Tags”,其中大多数是一些XML-Parser-Handlers使用的标记。但也用于序列化数据。它们被定义为空白:

  

public static String PROXY,NAME,X,Y,KEY,... CODES;

并用自己的名字初始化:

static {
    Field[] fields = Tags.class.getFields();
    for (int i = 0; i < fields.length; ++i) {
        try {
            // init field by its lowercased name
            String value = fields[i].getName().toLowerCase();
            fields[i].set(null, value);
        } catch (Exception e) {
            // exception should not occur, because only strings over here.
            e.printStackTrace();
        }
    }
}

你认为这有意义吗? 优点:

  • 所有标签在一个地方
  • 保证姓名与对应之间的对应关系价值(没有错误输入)
  • 在键入
  • 时通过IDE自动完成支持

缺点:

  • 不是真正的常数(不是最终的)
  • 可读性 - 只使用字符串文字“proxy”,“name”等会更直接
  • 反射初始化会消耗处理时间 - 延迟启动时间

那么 - 保留它还是重构它?

2 个答案:

答案 0 :(得分:4)

您可以通过枚举替换这些常量,并保持您列出的优势:

public enum Tags {
    PROXY("proxy"), 
    NAME("name"), 
    X("x"), 
    Y("y");

    public final String value;

    private Tags(String value) {
        this.value = value;

        if (!value.equals(name().toLowerCase())) {
            throw new RuntimeException("Value and name do not match");
        }
    }

    public static void main(String[] args) {
        for (Tags tag : Tags.values()) {
            System.out.println(tag + "\t" + tag.value);
        }
    }
}

在上面的代码中,测试value.equals(name().toLowerCase())不是必需的,但您似乎担心错误输入错误

答案 1 :(得分:3)

试试这个:

enum Enum {
    PROXY, NAME, X, Y;
    public String toString() { 
        return name().toLowerCase();
    }
}

或者这个:

public enum Tags {
    proxy, name, x, y
}