Enum的toString方法和Java的良好实践

时间:2015-02-24 10:40:25

标签: java jsf enums

我想问一下Java中的良好编码实践。我想创建一些属性的enumeratoin并覆盖toString()以便以下列方式使用它(JSF 1.2用于检索本地化消息):

package ua.com.winforce.casino.email.util;

import java.text.MessageFormat;
import java.util.Locale;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import javax.faces.context.FacesContext;

public enum StatisticItems {
    MESSAGES,
    VIEWS;

    private static String BUNDLE_NAME = "messages";

    public String toString(){
        switch (this) {
        case MESSAGES:
            return getLocalizedMsg("messages.title");
        case VIEWS:
            return getLocalizedMsg("views.title");
        default:
            return null;
        }
    }

    private static String getLocalizedMsg(String key, Object... arguments) {
        Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
        String resourceString;
        try {
            ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME, locale);
            resourceString = bundle.getString(key);
        } catch (MissingResourceException e) {
            return key;
        }

        if (arguments == null) {
            return resourceString;
        }
        MessageFormat format = new MessageFormat(resourceString, locale);
        return format.format(arguments);
    }
}

我的问题是好的做法。将所有这些方法置于enum定义中是否被认为是好的?如果没有,我想了解为什么以及如何做得更好。

2 个答案:

答案 0 :(得分:2)

这里有两点要点:

  1. 如果默认情况(在代码中返回null)是运行时错误,那么使用switch有点容易出错。在我看来,有两个更好的选择:

    1. 使用在枚举实例的构造函数中初始化的字段localizationKey,并在toString方法中引用此键
    2. 或者,(对于更复杂的情况)使toString抽象并强制每个实例覆盖正确的实现。例如,请参阅this question
  2. 许多人认为toString的目的是为了真正明显的实现,否则只用于调试。 (请参阅this question以获得详细说明。)我的建议:提出一个更具描述性的方法名称,不要仅仅为了方便而重复使用toString

  3. 更新:稍微缩短Java语义:这个逻辑属于视图而不是模型,正如BalusC在下面的评论中指出的那样。

答案 1 :(得分:0)

我会确保所有复杂的逻辑只在初始化时完成一次。

public enum StatisticItems {

    MESSAGES("messages"),
    VIEWS("views");
    final String asString;

    StatisticItems(String localised) {
        asString = getLocalizedMsg(localised + ".title");
    }

    @Override
    public String toString () {
        return asString;
    }

    private static String BUNDLE_NAME = "messages";
    private static final Locale locale = FacesContext.getCurrentInstance().getViewRoot().getLocale();
    private static final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_NAME, locale);

    private static String getLocalizedMsg(String key) {
        String resourceString;
        try {
            resourceString = bundle.getString(key);
        } catch (MissingResourceException e) {
            return key;
        }

        if (arguments == null) {
            return resourceString;
        }
        MessageFormat format = new MessageFormat(resourceString, locale);
        return format.format(arguments);
    }
}