Java 如何定义枚举项的属性
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3054247/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to define properties for Enum items
提问by iTEgg
I have read the question Difference of Enum between java and C++?but I'm still confused.
我已经阅读了Java 和 C++ 之间 Enum 的差异问题?但我还是很困惑。
I would like the following to return the related String:
我希望以下内容返回相关的字符串:
public enum Checker {
EMPTY ("Empty"),
RED ("Red"),
YELLOW ("Yellow");
}
From what I have read, this should be possible. Just would like you to shed some light on it on how to implement it.
从我所读到的,这应该是可能的。只是希望您对如何实施它有所了解。
采纳答案by Sean Patrick Floyd
Short Answer
简答
You need a constructor, a field and a getter.
您需要一个构造函数、一个字段和一个 getter。
Constructors
构造函数
Enum types can have constructors, provided that their access level is either private or default (package-private). You can not directly call these constructors, except in the enum declaration itself. Similar to classes, when you define an enum constant without parameters, you actually call the default constructor generated by the compiler. E.g.
枚举类型可以有构造函数,前提是它们的访问级别是私有的或默认的(包私有)。您不能直接调用这些构造函数,除非在枚举声明本身中。与类类似,当你定义一个不带参数的枚举常量时,实际上是调用了编译器生成的默认构造函数。例如
public enum King {
ELVIS
}
is equivalent to
相当于
public enum King {
ELVIS() // the compiler will happily accept this
}
And just like in classes, if you define an explicit constructor, the compiler will not insert a default constructor, so this will not compile:
就像在类中一样,如果定义显式构造函数,编译器将不会插入默认构造函数,因此不会编译:
public enum King {
ELVIS, // error, default constructor is not defined
MICHAEL_HymanSON(true)
;
private boolean kingOfPop;
King(boolean kingOfPop){this.kingOfPop = kingOfPop;}
}
This is a pretty good reference on enumsthat also explains the constructor issues.
这是一个很好的枚举参考,也解释了构造函数问题。
Fields and Accessors
字段和访问器
Enums are constants and are immutable as such. They can however define fields, that can have state. This is an awful practice, because developers will expect enums and their associated values to be constants, but you canstill define a non-final field in an enum with getters and setters.
枚举是常量,因此是不可变的。然而,他们可以定义可以有状态的字段。这是一个可怕的做法,因为开发商会希望枚举和它们相关联的值是常量,但你可以仍然与getter和setter枚举定义一个非最终场。
This is legal java code:
这是合法的Java代码:
public enum Color {
RED("FF0000"),
GREEN("00FF00"),
BLUE("0000FF");
private String code;
public String getCode(){return code;}
public void setCode(String code){this.code = code;}
private Color(String code){this.code = code;}
}
But it enables evil code like this:
但它启用了这样的邪恶代码:
String oldBlue = Color.BLUE.getCode();
Color.BLUE.setCode(Color.RED.getCode());
Color.RED.setCode(oldBlue);
So in 99.99 % of cases: if you have fields in your enums, you should make them final and provide getters only. If the fields are not immutable themselves, provide defensive copies:
所以在 99.99% 的情况下:如果你的枚举中有字段,你应该将它们设为 final 并只提供 getter。如果字段本身不是不可变的,请提供防御性副本:
public enum Band {
THE_BEATLES("John","Paul","George","Ringo");
private final List<String> members;
public List<String> getMembers(){
// defensive copy, because the original list is mutable
return new ArrayList<String>(members);
}
private Band(String... members){
this.members=Arrays.asList(members);
}
}
Solution
解决方案
In your case it's very simple: you just need a single field of type string (immutable), so initializing it in the constructor and providing a getter is perfectly ok:
在您的情况下,它非常简单:您只需要一个字符串类型(不可变)的字段,因此在构造函数中初始化它并提供一个 getter 是完全可以的:
public enum Checker {
EMPTY ("Empty"),
RED ("Red"),
YELLOW ("Yellow");
private final String value;
private Checker(final String value) {
this.value = value;
}
public String getValue() { return value; }
}
回答by Michael Borgwardt
If the pattern holds, this works as well and eliminates the repetition:
如果模式成立,这也有效并消除重复:
public enum Checker {
EMPTY,
RED,
YELLOW;
public String getDescription(){
String name = name();
return ""+Character.toUpperCase(name.charAt(0))
+name.substring(1).toLowerCase();
}
}