是否存在在Java中命名枚举的约定?
我的偏好是枚举是一种类型。所以,例如,你有一个枚举
Fruit{Apple,Orange,Banana,Pear, ... }
NetworkConnectionType{LAN,Data_3g,Data_4g, ... }
我反对命名它:
FruitEnum
NetworkConnectionTypeEnum
我知道很容易找出哪些文件是枚举,但是你也可以:
NetworkConnectionClass
FruitClass
另外,是否有一个好的文档描述常量,声明它们等等?
答案 0 :(得分:418)
枚举是类,应遵循类的约定。枚举的实例是常量,应遵循常量的约定。所以
enum Fruit {APPLE, ORANGE, BANANA, PEAR};
除了FruitClass之外,没有理由编写FruitEnum。你只是在浪费四个(或五个)字符而不添加任何信息。
Java本身推荐这种方法,它是used in their examples。
答案 1 :(得分:69)
这可能不会让我成为很多新朋友,但应该补充说C#人有不同的准则:枚举实例是“Pascal case”(大小写混合)。请参阅stackoverflow discussion和MSDN Enumeration Type Naming Guidelines。
当我们与C#系统交换数据时,我很想完全复制它们的枚举,而忽略了Java的“常量具有大写名称”约定。考虑到这一点,我没有看到枚举实例限制为大写的重要性。出于某些目的,.name()是获取枚举常量的可读表示的便捷快捷方式,并且混合大小写的名称看起来更好。
所以,是的,我敢于质疑Java枚举命名约定的价值。 “编程世界的另一半”确实使用了不同的风格这一事实让我觉得怀疑自己的宗教是合法的。
答案 2 :(得分:17)
如前所述,根据Oracle网站(BindFlags
)上的文档,枚举实例应为大写。
然而,在查看Oracle网站(http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)上的JavaEE7教程时,我偶然发现了“Duke的书店”教程和类(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;
}
}
所以看起来甚至甲骨文的人都有时会以方便的方式进行交易。
答案 3 :(得分:13)
在我们的代码库中;我们通常在他们所属的类中声明枚举。
因此,对于你的Fruit示例,我们将有一个Fruit类,并且在其中有一个名为Fruits的Enum。
在代码中引用它如下所示:Fruit.Fruits.Apple, Fruit.Fruits.Pear
等。
常量沿着同一行,它们要么在它们相关的类中被定义(所以类似Fruit.ORANGE_BUSHEL_SIZE
);或者,如果它们在名为“ConstantManager”的类(或类似的ConstantManager.NULL_INT
)中应用系统范围(即int的等效“null值”)。 (旁注;我们所有的常数都是大写的)
与往常一样,您的编码标准可能与我的不同;所以YMMV。
答案 4 :(得分:7)
它们仍然是类型,所以我总是使用我用于类的相同命名约定。
我绝对不赞成将“Class”或“Enum”放在名字中。如果您同时拥有FruitClass
和FruitEnum
,则其他内容出错,您需要更多描述性名称。我正在尝试考虑导致需要两者的代码类型,并且似乎应该有一个带有子类型而不是枚举的Fruit
基类。 (这只是我自己的猜测,你可能会遇到与我想象的情况不同的情况。)
我可以找到命名常量的最佳参考来自Variables tutorial:
如果您选择的名称只包含一个单词,则拼写全部小写字母。如果它由多个单词组成,则将每个后续单词的首字母大写。名称gearRatio和currentGear是此约定的主要示例。如果变量存储常量值,例如static final int NUM_GEARS = 6,则约定会略有变化,将每个字母大写并用后缀字符分隔后续单词。按照惯例,下划线字符从未在别处使用过。
答案 5 :(得分: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 }
}
所以我猜全部大写更严格,但我仍然使用类名约定,因为我讨厌所有大写
答案 6 :(得分:0)
如果我可以添加0.02美元,我更喜欢使用PascalCase作为C中的枚举值。
在C中,它们基本上是全局的,而且PEER_CONNECTED与PeerConnected相比真的很累。
呼吸新鲜空气。
从字面上看,它让我更容易呼吸。
在Java中,只要您从另一个类静态导入它们,就可以使用原始枚举名称。
import static pkg.EnumClass.*;
现在,您可以使用已经以不同方式限定的非限定名称。
我目前(思考)将一些C代码移植到Java,并且当前在选择Java约定(更冗长,更冗长,更丑陋)和我的C风格之间“撕裂”。
PeerConnected将变为PeerState.CONNECTED,但在switch语句中,它是CONNECTED。
现在对于后一种惯例有很多话要说它确实看起来不错,但某些“惯用语”如if (s == PeerAvailable)
变得像if (s == PeerState.AVAILABLE)
而且怀旧,这对我来说是一种失去意义。
我认为我仍然更喜欢Java风格,但是我很难看到尖叫的代码。
现在我意识到PascalCase已经在Java中被广泛使用,但它实际上并不是很混乱,只是有点不合适。