Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 枚举的可维护性是否低于公共静态最终常量?_Java_Performance_Enums_Constants_Maintainability - Fatal编程技术网

Java 枚举的可维护性是否低于公共静态最终常量?

Java 枚举的可维护性是否低于公共静态最终常量?,java,performance,enums,constants,maintainability,Java,Performance,Enums,Constants,Maintainability,我最近和一个朋友讨论了枚举与公共静态最终常量的关系。我告诉他,公共静态最终常量比枚举更易于维护,有时更快(android开发者文档证实了这一点),也更方便。我还说过,使用枚举时也会失去功能: 不能扩展枚举 不能实例化枚举 然后他说,如果需要实例化或扩展枚举,就不应该使用枚举。然后我回答说,这就是为什么我们应该只使用常量,因为它更易于维护;如果项目中期我们需要实例化或扩展枚举,该怎么办?那我们就必须改变一切 我举了一个例子来演示枚举与常量,以说明我的观点: public enum WeekDay

我最近和一个朋友讨论了枚举与公共静态最终常量的关系。我告诉他,公共静态最终常量比枚举更易于维护,有时更快(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");
    
        }
    }
    
    然后我可以扩展它,使美国的工作日:

    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,您可能可以使用数据结构(列表)来解决问题,这样您就可以克服这个缺点,但为什么还要麻烦呢?通过使用公共静态常量,我从基类、更干净的代码、可能更短的代码和更易于维护的代码中获得了继承

    我还了解到,您可以使用enum更好地设计“输入参数”,但也可以对公共静态最终常量进行同样的设计,如上所示

    枚举的优点是可以在switch语句中使用,并具有继承的枚举方法,如values()。如果需要,也可以在“公共静态最终常量”类中复制这些方法。除了切换之外,我看不到枚举的任何优势

    总之,枚举真的比公共静态最终常量好吗?如果是这样,我错在哪里了?他们是我错过的东西吗

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

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

    我认为您将枚举的使用带到了很远的地方,然后得出结论,它们没有用

    枚举只是告诉您有有限的预定义的个选项可供选择。仅此而已。例如,当您看到一个参数是一个枚举(比如State),它有3个值(Pending、InProgress、Closed),您就知道某个对象的状态可以有其中一个值,并且只能有其中一个值


    枚举提供了一种简单的方法来验证是否使用了正确的值,因为编码时无法轻松选择不正确的值。它们也是一种记录方式,因为您可以很容易地看到哪些选项可用。

    枚举给您带来的好处远远超过您对它们的评价,虽然有时需要常量,但这种情况对于枚举来说可能是一种胜利

    首先,“英国工作日”和“西班牙工作日”之间没有真正的区别,它们代表相同的价值观。因此,最好的解决方案是通过某种本地化方法,独立于值的实际内容进行字符串转换。这些值不随语言的变化而变化,它们的表示形式会发生变化

    这完全可以通过enum快速轻松地实现。就这样写吧(有点假代码):

    你把外在表现和内在表现混为一谈。你的数据应该尽可能的同质化,因为只有一个星期一。它可能被称为不同的东西,但它仍然是相同的值


    Enum还免费为您提供了很多好处,从长远来看,这使您的代码更清晰,更易于维护。类型检查、
    ==
    比较和
    开关中的可用性是少数,没有样板可谈。

    静态final
    变量是如何可扩展的?我的意思是任何人都想知道的基本类,安卓R系统使用了我上面发布的类似结构。“枚举是否比公共静态最终常量更难维护?" .... 在得出适合您的用例的答案时,有很多方面必须考虑。任何试图为这个问题提供一个决定性的、普遍的是非答案的尝试都将失败。一个特别重要的方面是可序列化性。编写一个健壮、正确、实例控制且安全的可序列化Java类不是一件小事。有了Java枚举,您就可以免费获得它。为未来做计划不是更好(更易于维护)吗?您可以使用枚举限制您的选项。例如,我有枚举“State”。假设“State”枚举具有特定于对象“State”的方法,而不仅仅是“markers”,那么最好保持“多态”属性不变,以便我们可以在需要时重用代码,或者使用不同的对象?如果需要更复杂的结构,您可以创建一个类、方法,枚举应该是一个简单的结构-您并不总是需要过度复杂。限制选项正是枚举的用途。你总是可以给它们添加更多的值,“WeekDay”枚举只是一个(糟糕的)例子。在本例中,使用语言作为参数是“正确的方法”。至于切换,我们能不能只做一个映射?在这个例子中更好的表达方式是,如果西班牙或美国的工作日在其构造函数中有一个额外的参数。例如,我们可以在“ChristianWeekDay”上一节课,然后
    public enum Weekday {
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        ...;
    
        public String toLocalizedString(Language l) {
            // interact with localization files
        }
    }