Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.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_Enums_Coding Style_Verbose - Fatal编程技术网

Java 使用枚举的序号是一种好的做法吗?

Java 使用枚举的序号是一种好的做法吗?,java,enums,coding-style,verbose,Java,Enums,Coding Style,Verbose,我有一个枚举: public enum Persons { CHILD, PARENT, GRANDPARENT; } 使用ordinal()方法检查枚举成员之间的“层次结构”是否有问题?我的意思是-当使用它时,排除冗长,当有人可能在将来意外地改变顺序时,有什么缺点吗 还是这样做更好: public enum Persons { CHILD(0), PARENT(1), GRANDPARENT(2); private Intege

我有一个枚举:

public enum Persons {

    CHILD,
    PARENT,
    GRANDPARENT;

}
使用
ordinal()
方法检查枚举成员之间的“层次结构”是否有问题?我的意思是-当使用它时,排除冗长,当有人可能在将来意外地改变顺序时,有什么缺点吗

还是这样做更好:

public enum Persons {

    CHILD(0),
    PARENT(1),
    GRANDPARENT(2);

    private Integer hierarchy;

    private Persons(final Integer hierarchy) {
        this.hierarchy = hierarchy;
    }

    public Integer getHierarchy() {
        return hierarchy;
    }

}

我将使用您的第二个选项(使用显式整数),这样数值由您而不是由Java分配。

第一种方法是不可直接理解的,因为您必须阅读使用枚举的代码才能理解枚举的顺序。
它很容易出错

public enum Persons {

    CHILD,
    PARENT,
    GRANDPARENT;

}
第二种方法更好,因为它是不言自明的:

CHILD(0),
PARENT(1),
GRANDPARENT(2);

private SourceType(final Integer hierarchy) {
    this.hierarchy = hierarchy;
}

当然,枚举值的顺序应该与枚举构造函数参数提供的层次顺序一致。

它引入了一种冗余,因为枚举值和枚举构造函数的参数都传达了它们的层次结构。
但为什么会有问题?
枚举用于表示常量且不经常更改的值
OP enum用法很好地说明了良好的enum用法:

CHILD, PARENT, GRANDPARENT
枚举不是为表示频繁移动的值而设计的。
在这种情况下,使用枚举可能不是最佳选择,因为它可能会频繁中断使用它的客户端代码,而且每次修改枚举值时都会强制重新编译、重新打包和重新部署应用程序。

使用
ordinal()
不推荐,因为枚举声明中的更改可能会影响序数值

更新:

值得注意的是,枚举字段是常量,可以有重复的值,即

enum Family {
    OFFSPRING(0),
    PARENT(1),
    GRANDPARENT(2),
    SIBLING(3),
    COUSING(4),
    UNCLE(4),
    AUNT(4);

    private final int hierarchy;

    private Family(int hierarchy) {
        this.hierarchy = hierarchy;
    }

    public int getHierarchy() {
        return hierarchy;
    }
}
这可能是有害的,也可能是有益的,这取决于您计划如何处理层次结构

此外,您可以使用枚举常量来构建自己的
enumglags
,而不是使用
EnumSet
,例如TLDR:No,您不应该

如果在
Enum.java
中为
ordinal
方法引用javadoc:

大多数程序员不会使用这种方法。它是 设计用于复杂的基于枚举的数据结构,如 作为
java.util.EnumSet
java.util.EnumMap

首先-阅读手册(本例中为javadoc)

其次,不要编写脆弱的代码。枚举值将来可能会更改,您的第二个代码示例将更加清晰和易于维护

根据java,如果(比如)在
父级
祖辈
之间插入新的枚举值,您肯定不想在将来产生问题

返回此枚举常量的序号(其在 枚举声明,其中初始常量被分配一个 零)。大多数程序员不会使用这种方法。它是 设计用于复杂的基于枚举的数据结构,如 枚举集和枚举映射

您可以通过更改枚举的顺序来控制序号,但不能显式设置。一种解决方法是在枚举中为所需的数字提供一个额外的方法

enum Mobile {
   Samsung(400), Nokia(250),Motorola(325);

   private final int val;
  private Mobile (int v) { val = v; }
  public int getVal() { return val; }
}

在这种情况下,
Samsung.ordinal()=0
,但是
Samsung.getVal()=400

首先,您可能甚至不需要数字顺序值——这就是 什么 用于,并且
Enum
实现
可比

如果出于某种原因确实需要一个数字订单值,是的,您应该这样做 使用
ordinal()
。这就是它的目的

Java
Enums
的标准实践是按声明顺序排序, 这就是为什么
Enum
实现了
compariable
以及为什么
Enum.compareTo()
final

如果您添加自己的非标准比较代码,而该代码不使用
可比性
不依赖于申报顺序,您只需 这会让其他试图使用你的代码的人感到困惑,包括 你自己未来的自我。没有人会期望代码存在; 他们希望
Enum
Enum

如果自定义订单与声明订单不匹配,任何人 看这份声明会感到困惑。如果有 (此时正好)符合申报顺序,有人吗 看着它,人们会想到这一点,他们也会想到这一点 在未来的某个日子里,如果没有,你会受到严重的打击。(如果你写信 编码(或测试)以确保自定义顺序与 声明顺序,您只是在强调它是多么不必要。)

如果您增加了自己的订单价值,那么您就造成了维护方面的麻烦 为你自己:

  • 您需要确保您的
    层次结构
    值是唯一的
  • 如果您在中间添加一个值,则需要重新编号。 后续值 如果您担心有人可能会意外更改订单 以后,编写一个检查顺序的单元测试

    总之,用不朽的话来说: 了解并使用图书馆



    另外,当您的意思是
    int
    时,不要使用
    Integer
    如果只想在枚举值之间创建关系,实际上可以使用使用其他枚举值的技巧:


    请注意,您只能使用在您试图声明的枚举值之前按词汇声明的枚举值,因此只有当您的关系形成一个无环有向图(并且您声明它们的顺序是有效的拓扑排序)时,这才有效。

    正如Joshua Bloch在《有效Java》中所建议的那样,从序号派生与枚举关联的值不是一个好主意,因为更改枚举值的顺序可能会破坏编码的逻辑

    您提到的第二种方法完全遵循作者的建议,即将价值存储在单独的fie中
    public enum Person {
      GRANDPARENT(null),
      PARENT(GRANDPARENT),
      CHILD(PARENT);
    
      private final Person parent;
    
      private Person(Person parent) {
        this.parent = parent;
      }
    
      public final Parent getParent() {
        return parent;
      }
    }
    
    public class Persons {
        final public static int CHILD = 0;
        final public static int PARENT = 1;
        final public static int GRANDPARENT = 2;
    }
    
    Persons.CHILD
    
     @Bean
      public FilterRegistrationBean compressingFilterRegistration() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(compressingFilter());
        registration.setName("CompressingFilter");
        ...
        registration.setOrder(1);
        return registration;
      }
    
       enum FilterRegistrationOrder {
        MDC_FILTER,
        COMPRESSING_FILTER,
        CACHE_CONTROL_FILTER,
        SPRING_SECURITY_FILTER,
        ...
        }