【发布时间】:2013-12-31 18:39:30
【问题描述】:
我最近在和朋友讨论枚举与公共静态最终常量。我告诉他公共静态最终常量比枚举更易于维护,有时更快(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
*/
}
}
我了解使用枚举您也许可以使用数据结构(列表)来解决这个问题,这样您就可以适应这个缺点,但为什么要麻烦呢?通过使用公共静态常量,我获得了从基类的继承、更简洁的代码、可能更短的代码以及更易于维护。
我还读到您可以使用枚举来更好地设计“输入参数”,但您也可以对公共静态最终常量执行相同的操作,如上所示。
枚举的优点是可以在 switch 语句中使用,并且具有继承的枚举方法,如 values()。如果需要,这些方法也可以在“公共静态最终常量”类中复制。除了开关之外,我没有看到任何枚举优势。
总之,枚举真的比公共静态最终常量更好吗?如果是这样,我哪里出错了?他们是我缺少的东西吗?
编辑: 您也不能在枚举中使用泛型。
【问题讨论】:
-
static final变量如何扩展? -
我的意思是基类
-
对于任何想知道的人,android R 系统使用了我在上面发布的类似结构。
-
“枚举比公共静态最终常量更难维护吗?” .... 在得出适合您的答案时,必须考虑很多方面用例。任何试图为这个问题提供一个决定性的、普遍的“是-否”答案的尝试都将失败。一个特别重要的方面是可串行化。编写一个健壮、正确、实例控制和安全可串行化的Java类不是小事。使用 Java 枚举,您可以免费获得它。
标签: java performance enums constants maintainability