我最近和朋友讨论了枚举与公共静态最终常量。我告诉他,公共静态最终常量比枚举更易于维护,有时更快(android开发人员文档确认这一点),也更方便。我还说过在使用枚举时你也失去了功能:
然后他说如果你需要实例化或扩展枚举,你不应该使用枚举。然后我回答说这就是为什么我们应该只使用常量,因为它更易于维护;如果中间项目需要实例化枚举或扩展它,该怎么办?然后我们必须改变一切。
演示枚举与常量的示例,用于说明我的观点:
public enum WeekDay {
/*
* We will start at 1 for demonstration
*/
SUNDAY("Sunday", 1), MONDAY("Monday", 2), TUESDAY("Tuesday", 3), WEDNESDAY(
"Wednesday", 4), THURSDAY("Thursday", 5), FRIDAY("Friday", 6), SATURDAY(
"Saturday", 7);
/*
* Notice we cannot do this...This is where enums fail.
*/
// LUNES("lunes",1), MARTES("martes",2);
private String dayName;
private int dayIndex;
private WeekDay(String dayName, int dayIndex) {
this.dayName = dayName;
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
@Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
}
如果我们还需要西班牙语周工作日怎么办?枚举不足,因为你无法扩展它(你必须做一些复制和粘贴动作)。
将枚举与此对比:
public class WeekDayClass {
private int dayIndex;
private String dayName;
public WeekDayClass(int dayIndex, String dayName) {
super();
this.dayIndex = dayIndex;
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
@Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
abstract static class Constants {
}
public static void main(String[] args) {
WeekDayClass init = new WeekDayClass(10, "I can init new days here");
}
}
然后我可以扩展它并制作AmericanWeekDays:
public class AmericanWeekDay extends WeekDayClass {
public AmericanWeekDay(int dayIndex, String dayName) {
super(dayIndex, dayName);
}
static class AmericanConstants extends Constants {
public static final WeekDayClass SUNDAY = new WeekDayClass(1, "Sunday");
public static final WeekDayClass MONDAY = new WeekDayClass(2, "Monday");
/*
* And so on...
*/
}
}
或西班牙周日:
public class SpanishWeekDays extends WeekDayClass {
public SpanishWeekDays(int dayIndex, String dayName) {
super(dayIndex, dayName);
}
static class SpanishConstants extends Constants {
public static final SpanishWeekDays LUNES = new SpanishWeekDays(2, "lunes");
/*
* And so on...
*/
}
}
还要走得更远:
public class WeekDayClass {
private int dayIndex;
private String dayName;
public WeekDayClass(int dayIndex, String dayName) {
super();
this.dayIndex = dayIndex;
this.dayName = dayName;
}
public int getDayIndex() {
return dayIndex;
}
public void setDayIndex(int dayIndex) {
this.dayIndex = dayIndex;
}
public String getDayName() {
return dayName;
}
public void setDayName(String dayName) {
this.dayName = dayName;
}
@Override
public String toString() {
return this.dayName + ": " + this.dayIndex;
}
static class AmericanConstants {
/*
* Insert Constants Here
*/
}
static class SpanishConstants {
/*
* Insert Constants Here
*/
}
}
我理解使用枚举你可以使用数据结构(列表)来解决这个问题,这样你就可以解决这个缺点但是为什么要这么麻烦呢?使用公共静态常量,我从基类获得继承,更清晰的代码,可能更短的代码,更容易维护。
我还读到你可以使用enum来更好地设计“输入参数”,但你也可以使用公共静态最终常量来做同样的事情,如上所示。
枚举的优点是能够在switch语句中使用,并具有继承的枚举方法,如values()。如果在“public static final constant”类中需要,也可以复制这些方法。除了开关之外,我没有看到任何枚举优势。
总之,enum真的比公共静态最终常量更好吗?如果是的话,我哪里出错了?他们是我失踪的东西吗?
编辑: 您也不能在枚举中使用泛型。
答案 0 :(得分:9)
Enums比你似乎给予他们更多的荣誉,虽然有时需要常量,但这个案例可能是枚举的胜利。
首先,“英语工作日”和“西班牙语工作日”之间没有真正的区别,它们代表相同的值。因此,最好的解决方案是通过某种定位方法独立于实际值的转换。这些值不随语言而改变,它们的表示也是如此。
使用枚举可以快速轻松地完成这项工作。就这样写一下(有点伪代码):
public enum Weekday {
MONDAY,
TUESDAY,
WEDNESDAY,
...;
public String toLocalizedString(Language l) {
// interact with localization files
}
}
您正在混淆外部代表和内部代表的想法。您的数据应尽可能保持同质,因为周一只有一个。它可能被称为不同的东西,但它仍然是相同的值。
Enums也可以免费为您带来很多好处,从长远来看,这使您的代码更清晰,更易于维护。 ==
中的类型检查,switch
比较和可用性是少数,没有样板可以说。
答案 1 :(得分:5)
我认为你将enums的使用方式推向远方,然后得出它们没用的结论。
枚举只是告诉您有一个有限和预定义数量的选项可供选择。 只不过是。例如,当您看到一个枚举参数(让我们说State)并且它有3个值(Pending,InProgress,Closed)时,您知道某个对象的状态可以包含其中一个且只有其中一个值。
枚举提供了一种简单的方法来验证是否使用了正确的值,因为您无法轻松选择编码时不正确的值。它们也是一种记录方式,因为您可以轻松查看可用的选项。
答案 2 :(得分:1)
如果它们没用,枚举就不存在 - 常量也是如此。就像一把螺丝刀可以移除螺丝,而锤子可以移除钉子 - 程序员“工具箱”中的不同工具可用于独特和重要的目的。我建议阅读更多关于枚举和常量的内容,我想你会发现它们存在的原因以及何时使用它们。