name()静态方法通常为您执行将字符串映射到枚举值的操作。 因此,如果您想使用同义词来完成此操作,则必须开发类似的东西。 但是,我们不想让我们可以覆盖静态方法,因此我们为此使用不同的名称:valueOf应该是适当的。
public enum Language {
ENGLISH("eng", "en", "en_GB", "en_US"),
GERMAN("de", "ge"),
CROATIAN("hr", "cro"),
RUSSIAN("ru"),
BELGIAN("be",";-)");
static final private Map ALIAS_MAP = new HashMap();
static {
for (Language language:Language.values()) {
// ignoring the case by normalizing to uppercase
ALIAS_MAP.put(language.name().toUpperCase(),language);
for (String alias:language.aliases)
ALIAS_MAP.put(alias.toUpperCase(),language);
}
}
static public boolean has(String value) {
// ignoring the case by normalizing to uppercase
return ALIAS_MAP.containsKey(value.toUpperCase());
}
static public Language fromString(String value) {
if (value == null) throw new NullPointerException("alias null");
Language language = ALIAS_MAP.get(value.toUpperCase());
if (language == null)
throw new IllegalArgumentException("Not an alias: "+value);
return language;
}
private List aliases;
private Language(String... aliases) {
this.aliases = Arrays.asList(aliases);
}
}
作为这种实现方式的好处,我们可以证明,也可以轻松地实现name()静态方法来测试给定别名是否为枚举值集的一部分。 同时,我们应用了一些良好的命名约定:
枚举值以大写形式表示,表示它们实际上是静态的final(单个实例)。
同时,我们也将所有其他静态决赛的大写上限。
请注意,我们不必重复枚举值本身的名称:我们始终会自动考虑它自己的名称(将其添加到ALIAS_MAP中),然后在顶部将所有内容标准化为大写以使其不区分大小写。
看起来很大,但是使用枚举时看起来很漂亮:
public void main() {
Language myLanguage = Language.fromString("en_GB");
if (myLanguage == Language.ENGLISH) {
System.out.println("Yes, I know, you understand English!");
}
}
别名的后备容器是name(),更具体地说是valueOf。 HashMap提供了对别名的快速访问路径,并且易于扩展。 每当我们考虑对某事进行“索引编制”时,我们最好选择HashMap。
请注意,为透明起见,我们既存储枚举常量本身的名称(通过name()方法检索),又存储所有别名。 我们可以通过先尝试使用内置的valueOf静态方法进行查找来实现不同的实现。 这是一种设计选择,但我们可能必须处理其他异常等。