枚举是否比公共静态最终常量更难维护?

时间:2013-12-13 04:14:44

标签: java performance enums constants maintainability

我最近和朋友讨论了枚举与公共静态最终常量。我告诉他,公共静态最终常量比枚举更易于维护,有时更快(android开发人员文档确认这一点),也更方便。我还说过在使用枚举时你也失去了功能:

  1. 您无法扩展枚举。
  2. 您无法实例化枚举。
  3. 然后他说如果你需要实例化或扩展枚举,你不应该使用枚举。然后我回答说这就是为什么我们应该只使用常量,因为它更易于维护;如果中间项目需要实例化枚举或扩展它,该怎么办?然后我们必须改变一切。

    演示枚举与常量的示例,用于说明我的观点:

    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真的比公共静态最终常量更好吗?如果是的话,我哪里出错了?他们是我失踪的东西吗?

    编辑: 您也不能在枚举中使用泛型。

3 个答案:

答案 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)

如果它们没用,枚举就不存在 - 常量也是如此。就像一把螺丝刀可以移除螺丝,而锤子可以移除钉子 - 程序员“工具箱”中的不同工具可用于独特和重要的目的。我建议阅读更多关于枚举和常量的内容,我想你会发现它们存在的原因以及何时使用它们。