编码约定-命名枚举


289

是否有使用Java命名枚举的约定?

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

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

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

我反对为其命名:

FruitEnum
NetworkConnectionTypeEnum

我知道很容易挑选出哪些文件是枚举,但随后您还将拥有:

NetworkConnectionClass
FruitClass

另外,是否有一个很好的文档对常量进行了描述,在何处声明了常量等?


2
请使其成为社区Wiki。由于没有一个可接受的答案,否则它将被关闭。
Alexander Pogrebnyak 2010年

13
@Alexander Pogrebnyak不,有一个答案。
Tom Hawtin-大头钉

Answers:


473

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

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

除了FruitClass之外,没有其他理由编写FruitEnum了。您只是浪费了四个(或五个)不添加任何信息的字符。

Java本身推荐这种方法,并在示例中使用了这种方法。


22
我开始用这种方式来命名枚举,但是为了便于阅读,我现在使用的是Fruit.Apple而不是Fruit.APPLE。

38
@Walter为什么使枚举实例看起来像是一个类可以提高可读性?
DJClayworth 2010年

17
从技术上讲,枚举实例类。这就是为什么他们可以有方法的原因。
特德·霍普

87
不,枚举实例是一个实例。枚举是一类。
DJClayworth

30
使我键入Fruit.APPLE.chew()的命名模式的想法确实使我很烦。同样,尽管这将是非常糟糕的做法,但APPLE不必一定是常量(不可变)。有了的东西,甚至没有在存在C开发推广枚举到我不知道使用约定完整的Java类的(对象,而不是枚举)总是有意义的
比尔ķ

76

这可能不会让我结识很多新朋友,但应该补充一点,C#员工有不同的准则:枚举实例为“ Pascal大小写”(大小写混合)。请参阅stackoverflow讨论MSDN枚举类型命名准则

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

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


7
TIL只有Java或C#程序员是真正的程序员,他们的数量是相等的。#sarcasm
Mindwin'5

14
C#是另外一种很棒的语言,但这简直是愚蠢的。在C#中,一切几乎都是Pascal的情况,基本上与根本没有命名约定的情况相同。看名字你一无所获。您无法确定它是否是类,方法,属性等
。– Bassinator

3
同样,布尔值实际上是一个枚举,实例为真和假(用小写)。因此,是的,所有上限都很丑陋。
Florian F

@FlorianF,请勿将主要类型boolean与Boolean类(docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html)混淆。该类确实使用大写约定
IvoC

24

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

但是,在浏览Oracle网站(http://www.oracle.com/technetwork/java/javaee/downloads/index.html)上的JavaEE7教程时,我偶然发现了“ Duke's bookstore”教程和一个类(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;
    }
}

因此,即使是Oracle的员工有时也会很方便地进行交易约定。


13

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

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

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

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

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


5
我想补充一点,现在看来对象工厂是使用复数形式命名的,例如ListsMaps。我认为这是一个很好的约定,我完全支持它的更广泛使用。
Esko 2010年

是的,它们类似于我的个人编码标准,但不同于我的工作场所编码标准。我们没有很多工作标准,所以我试图找到一个很好的文档作为参考。

8
Fruit.Fruits.Apple对我来说太冗长了,从字面上打破了DRY原则:-)我宁愿例如Fruit.Type.APPLE
彼得Török

2
我不喜欢这种方法。苹果的命名方式要么是“水果”,要么至少是令人困惑的,因为尚不清楚苹果不是“水果”。我喜欢Peter的Type示例。至少然后,它可以自我证明APPLE是一种水果。虽然这整个水果的例子闻起来有点烂...
马克·彼得斯

1
我也不喜欢这样 如果“水果”类代表一种水果(并且应该),那么“水果”可以代表什么?如果Fruit(该类)确实是处理Fruit的类,则应将其重命名为“ FruitHandler”或“ FruitManager”
DJClayworth 2010年

7

它们仍然是类型,因此我始终使用与类相同的命名约定。

我绝对不会在名称中加上“ Class”或“ Enum”。如果您同时拥有a FruitClass和a,FruitEnum那么其他地方就不对了,您需要更具描述性的名称。我正在尝试考虑导致同时需要两者的代码类型,并且似乎应该有一个Fruit带有子类型而不是枚举的基类。(尽管这只是我自己的推测,但您可能遇到的情况与我想象的情况有所不同。)

我可以找到的有关命名常量的最佳参考来自“ 变量”教程

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



1

如果我可以添加$ 0.02,则我更喜欢使用PascalCase作为C中的枚举值。

在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已经在Java中被广泛使用,但实际上并没有使它感到困惑,只是有点地方。


0
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 }
}

所以我猜所有大写字母严格来说是更正确的,但是我仍然使用类名约定,因为我讨厌任何地方的所有大写字母

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.