【问题标题】:Coding Conventions - Naming Enums编码约定 - 命名枚举
【发布时间】:2011-03-05 10:14:57
【问题描述】:

Java 中有命名枚举的约定吗?

我的偏好是枚举是一种类型。因此,例如,您有一个枚举

Fruit{Apple,Orange,Banana,Pear, ... }

NetworkConnectionType{LAN,Data_3g,Data_4g, ... }

我反对命名:

FruitEnum
NetworkConnectionTypeEnum

我知道很容易挑选出哪些文件是枚举,但是你也会有:

NetworkConnectionClass
FruitClass

另外,是否有一个很好的文档描述常量,在哪里声明它们等?

【问题讨论】:

    标签: java enums coding-style naming-conventions standards


    【解决方案1】:

    枚举是类,应该遵循类的约定。枚举的实例是常量,应该遵循常量的约定。所以

    enum Fruit {APPLE, ORANGE, BANANA, PEAR};
    

    没有理由写FruitEnum 超过FruitClass。您只是在浪费四个(或五个)没有添加信息的字符。

    The Java™ Tutorial's 示例本身推荐并使用此方法。

    【讨论】:

    • 我开始以这种方式命名我的枚举,但为了便于阅读,我现在一直使用 Fruit.Apple 而不是 Fruit.APPLE。
    • @Walter 为什么让枚举实例看起来像一个类会提高可读性?
    • 从技术上讲,枚举实例类。这就是为什么他们可以有方法。
    • 不,枚举实例就是一个实例。枚举就是一个类。
    • 让我输入 Fruit.APPLE.chew() 的命名模式的想法真的让我很烦。此外,虽然这将是一个非常糟糕的做法,但 APPLE 不必是一个常量(不可变的)。随着将枚举提升为完整的 java 类,我不确定使用为 c 中甚至不存在的东西(对象,而不是枚举)开发的约定总是有意义
    【解决方案2】:

    这可能不会让我结交很多新朋友,但应该补充一点,C# 人有不同的准则:枚举实例是“Pascal 大小写”(大写/小写混合)。见stackoverflow discussionMSDN Enumeration Type Naming Guidelines

    当我们与 C# 系统交换数据时,我很想完全复制它们的枚举,忽略 Java 的“常量具有大写名称”约定。考虑到这一点,我认为将枚举实例限制为大写并没有多大价值。出于某些目的,.name() 是获得枚举常量的可读表示的便捷快捷方式,混合大小写的名称看起来会更好。

    所以,是的,我敢于质疑 Java 枚举命名约定的价值。 “编程世界的另一半”确实使用了不同的风格这一事实让我认为怀疑我们自己的宗教是合理的。

    【讨论】:

    • TIL 只有 Java 或 C# 程序员才是真正的程序员,而且他们的人数是相等的。 #讽刺
    • C# 本来是一门很棒的语言,但这实在是太傻了。 Everything 在 C# 中几乎是帕斯卡大小写,这与完全没有命名约定基本相同;看名字你一无所获。你无法判断它是类、方法、属性等。
    • 另外,布尔实际上是一个枚举,实例是真假,小写。所以是的,所有的大写字母都很丑。
    • @FlorianF,不要将主要类型 boolean 与类 Boolean (docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html) 混淆。该类确实使用大写约定
    【解决方案3】:

    如前所述,根据 Oracle 网站 (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html) 上的文档,枚举实例应为大写。

    然而,在浏览 Oracle 网站 (http://www.oracle.com/technetwork/java/javaee/downloads/index.html) 上的 JavaEE7 教程时,我偶然发现了“杜克书店”教程,在课堂 (tutorial\examples\case-studies\dukes-bookstore\src\main\java\javaeetutorial\dukesbookstore\components\AreaComponent.java) 中,我发现了以下枚举定义:

    private enum PropertyKeys {
        alt, coords, shape, targetImage;
    }
    

    按照惯例,它应该是这样的:

    public enum PropertyKeys {
        ALT("alt"), COORDS("coords"), SHAPE("shape"), TARGET_IMAGE("targetImage");
    
        private final String val;
    
        private PropertyKeys(String val) {
            this.val = val;
        }
    
        @Override
        public String toString() {
            return val;
        }
    }
    

    因此,似乎即使是甲骨文公司的人有时也会为了方便而交易约定。

    【讨论】:

    • 这里的枚举名称也是错误的。它必须是 PropertyKey 而不是 PropertyKeys,因为这种类型的变量只代表一个键。
    【解决方案4】:

    在我们的代码库中;我们通常在它们所属的类中声明枚举。

    因此,对于您的 Fruit 示例,我们将有一个 Fruit 类,其中有一个名为 Fruits 的枚举。

    在代码中引用它看起来像这样:Fruit.Fruits.Apple, Fruit.Fruits.Pear

    常量遵循同一行,它们要么在与其相关的类中定义(比如Fruit.ORANGE_BUSHEL_SIZE);或者,如果它们在名为“ConstantManager”(或等效;如ConstantManager.NULL_INT)的类中应用系统范围(即整数的等效“空值”)。 (旁注;我们所有的常量都是大写的)

    与往常一样,您的编码标准可能与我的不同;所以YMMV。

    【讨论】:

    • 我想补充一点,现在对象工厂似乎使用复数命名,例如ListsMaps。在我看来,这是一个很好的约定,我完全支持更广泛地使用它。
    • 是的,它们与我的个人编码标准相似,但与我的工作场所编码标准不同。我们没有很多工作标准,所以我正在努力寻找一个好的文档作为参考。
    • Fruit.Fruits.Apple 对我来说太冗长了,从字面上打破了 DRY 原则 :-) 我更喜欢例如Fruit.Type.APPLE.
    • 我不喜欢这种方法。这个名字的方式,一个苹果要么是水果,要么至少它是令人困惑的,因为不清楚苹果不是水果。我喜欢彼得的类型示例。至少它是自我证明苹果是一种水果。虽然这整个水果的例子闻起来有点腐烂......
    • 我也不喜欢这个。如果“水果”类代表一种水果(它应该),那么“水果”可以代表什么?如果 Fruit(类)真的是一个处理 Fruit 的类,那么它应该重命名为“FruitHandler”或“FruitManager”。
    【解决方案5】:

    它们仍然是类型,所以我总是使用与类相同的命名约定。

    我绝对不会在名称中加上“Class”或“Enum”。如果您同时拥有FruitClassFruitEnum,那么还有其他问题,您需要更具描述性的名称。我正在尝试考虑导致两者都需要的代码类型,并且似乎应该有一个带有子类型而不是枚举的 Fruit 基类。 (不过这只是我自己的猜测,您的情况可能与我想象的不同。)

    我能找到的关于命名常量的最佳参考来自Variables tutorial

    如果您选择的名称仅包含一个单词,则将该单词拼写为所有小写字母。如果它包含多个单词,则将每个后续单词的第一个字母大写。名称 gearRatio 和 currentGear 是这个约定的主要例子。如果您的变量存储一个常量值,例如 static final int NUM_GEARS = 6,则约定会略有变化,将每个字母大写,并用下划线分隔后续单词。按照惯例,下划线字符从不在其他地方使用。

    【讨论】:

    【解决方案6】:

    如果我可以加上我的 0.02 美元,我更喜欢在 C 中使用 PascalCase 作为枚举值。

    在 C 中,它们基本上是全局的,与 PeerConnected 相比,PEER_CONNECTED 变得非常累人。

    呼吸新鲜空气。

    从字面上看,它让我呼吸更轻松。

    在 Java 中,只要从另一个类静态导入它们,就可以使用原始枚举名称。

    import static pkg.EnumClass.*;
    

    现在,您可以使用已经以不同方式限定的非限定名称。

    我目前(正在考虑)将一些 C 代码移植到 Java,目前在选择 Java 约定(更冗长、更冗长、更丑陋)和我的 C 风格之间“纠结”。

    PeerConnected 将变为 PeerState.CONNECTED,除非在 switch 语句中,它是 CONNECTED。

    现在对于后一种约定有很多话要说,它看起来确实不错,但是某些“惯用短语”,例如 if (s == PeerAvailable) 变得像 if (s == PeerState.AVAILABLE) 并且怀旧,这对我来说失去了意义。

    我认为我仍然更喜欢 Java 风格,因为它清晰,但我很难看到尖叫的代码。

    现在我意识到 PascalCase 已经在 J​​ava 中被广泛使用,但它并不是真的很令人困惑,只是有点不合适。

    【讨论】:

      【解决方案7】:
      enum MyEnum {VALUE_1,VALUE_2}
      

      是(大约)喜欢说

      class MyEnum {
      
          public static final MyEnum VALUE_1 = new MyEnum("VALUE_1");
          public static final MyEnum VALUE_2 = new MyEnum("VALUE_2");
      
          private final name;
      
          private MyEnum(String name) {
              this.name = name;
          }
      
          public String name() { return this.name }
      }
      

      所以我猜全部大写更严格,但我仍然使用类名约定,因为我讨厌所有地方都大写

      【讨论】:

        猜你喜欢
        • 2010-11-27
        • 1970-01-01
        • 1970-01-01
        • 2012-05-16
        • 2015-08-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多