305

Is there a convention for naming enumerations in Java?

My preference is that an enum is a type. So, for instance, you have an enum

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

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

I am opposed to naming it:

FruitEnum
NetworkConnectionTypeEnum

I understand it is easy to pick off which files are enums, but then you would also have:

NetworkConnectionClass
FruitClass

Also, is there a good document describing the same for constants, where to declare them, etc.?

Joshua Taylor
  • 80,876
  • 9
  • 135
  • 306

7 Answers7

494

Enums are classes and should follow the conventions for classes. Instances of an enum are constants and should follow the conventions for constants. So

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

There is no reason for writing FruitEnum any more than FruitClass. You are just wasting four (or five) characters that add no information.

Java itself recommends this approach and it is used in their examples.

gsamaras
  • 66,800
  • 33
  • 152
  • 256
DJClayworth
  • 24,627
  • 8
  • 50
  • 71
  • 27
    I started naming my enums that way, but for readability, I have now been using Fruit.Apple instead of Fruit.APPLE. –  Jun 18 '10 at 14:00
  • 39
    @Walter Why would making an enum instance look like it was a class enhance readability? – DJClayworth Jun 18 '10 at 21:15
  • 19
    Technically, enum instances _are_ classes. That's why they can have methods. – Ted Hopp Nov 15 '11 at 22:44
  • 96
    No, an enum instance is an instance. An enum is a class. – DJClayworth Nov 16 '11 at 18:59
  • 33
    The idea of a naming pattern that makes me type Fruit.APPLE.chew() really bugs me. Also, although it would be a very bad practice, APPLE doesn't have to be a constant (immutable). With the promotion of enums to full java classes I'm not sure using conventions developed for something that didn't even exist in c (Objects, not enums) always make sense – Bill K Feb 16 '12 at 22:52
  • Given that an instance of an enum is an instance that has public access, why don't you follow the instance naming practice? ex. Fruit.apple, Color.blue, etc. I agree with Bill K that Fruit.APPLE.chew() is really confusing. – Ryan Shillington Oct 02 '12 at 17:25
  • 13
    APPLE doesn't represent *an* apple, it represents the type APPLE. (We know this because there can only be one APPLE). You shouldn't be chewing the type, you should be chewing an instance of a class Apple (which might have a type indicator APPLE). – DJClayworth Nov 20 '12 at 14:35
  • 17
    Just for future reference, the [java people agree](http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html): `Because they are constants, the names of an enum type's fields are in uppercase letters.` – Lucas Dec 19 '12 at 22:26
  • 4
    @DJClayworth - "No, an enum instance is an instance. An enum is a class", If you have methods on your enum instances then files like "Fruit$1.class" get produced (otherwise they don't). So if they're classes or just instances depends on if the enum instances have methods. – Adrian Smith Mar 26 '13 at 11:37
  • 1
    @DJClayworth "You shouldn't be chewing the type..." true. One should submit methods to the enum, which make sense. Like Fruit#hasPits. So if some Food happens to have the APPLE enum assigned to it, one could determine if it has pits or not. – Torsten Sep 28 '13 at 21:56
  • 4
    Another argument for using upper-case enumeration values is they make it possible to use `Fruit.valueOf(fruitString.toUpperCase())`. (Since [valueOf](http://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html) is case sensitive, a mixed case enumeration value would require custom code to do this.) – Steve Chambers Nov 20 '13 at 11:14
  • 2
    Think of `...{APPLE,...` as: `static final Fruit APPLE = new Fruit();` the declaration of the field is static final, so it falls under the convention for constants. There shouldn't be too much mutable stuff at an Enum, otherwise your code stinks! Enums should only be a set of (static) predefined values. – Hardcoded Mar 17 '14 at 14:17
  • 5
    @Hardcoded, I agree wholeheartedly with everything **except** the implication that `static final` immediately falls under the convention of "constants." It is perfectly legitimate to have a `static final` variable that is itself mutable; e.g., `static final List sSeenItems` is declared `static final`, so its *reference* cannot change; but you **can** still `add()`, `remove()`, `clear()`, etc; therefore it *is not constant*. – Joe May 28 '14 at 19:47
  • The issue is not the convention for constants, it is the definition of one. The original Java coding standard actually did this, and it declared anything that would be followed by a '.' is not a constant. Basically, only final static literals followed this convention. CAPS.someMethod() is just fugly, and INMHO should not, in general, be used. – Robin Jun 23 '14 at 14:22
  • @Joe the list variable itself is a constant, since the referenced list is always the same. Sure you can change what's in the list, but that's far from been clean code and may be an idea for Mindprods "unmaintable code" – Hardcoded Jul 24 '14 at 12:10
  • 2
    @DJClayworth *"APPLE doesn't represent an apple, it represents the type APPLE."* - although I agree with your answer at 100%, I have to disagree with this sentence. APPLE is not a type, APPLE is an instance of Fruit, one of the few instances of Fruit, which exist in a finite number. – Joffrey Mar 31 '15 at 15:58
  • 4
    @BillK I'm personally not bothered by `Fruit.APPLE.chew()` in terms of case. APPLE is a constant reference, caps are fine to me. Maybe you're just not used to see constant references, as we mostly use constant primitives. We should as well use `private static final Logger LOG = ... ;`. – Joffrey Mar 31 '15 at 16:06
  • @RyanShillington but the instance naming practise *is* respected. Constant instances are caps, variable instances are lower camel case: http://stackoverflow.com/a/7259738/1540818 – Joffrey Mar 31 '15 at 16:10
  • 1
    If you want to reliably distinguish enums from classes you can adjust your IDE to format them differently. In my environment enums, classes, and interfaces are each different hues of purple. – J.Steve Jul 09 '15 at 20:19
  • 2
    How about [Collector.Characteristics](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collector.Characteristics.html)? – shmosel Jul 28 '15 at 22:54
  • Collector.Characteristics is a class and has three instances: UNORDERED, IDENTITY_FINISH and CONCURRENT. – DJClayworth Dec 20 '19 at 19:39
78

This will probably not make me a lot of new friends, but it should be added that the C# people have a different guideline: The enum instances are "Pascal case" (upper/lower case mixed). See stackoverflow discussion and MSDN Enumeration Type Naming Guidelines.

As we are exchanging data with a C# system, I am tempted to copy their enums exactly, ignoring Java's "constants have uppercase names" convention. Thinking about it, I don't see much value in being restricted to uppercase for enum instances. For some purposes .name() is a handy shortcut to get a readable representation of an enum constant and a mixed case name would look nicer.

So, yes, I dare question the value of the Java enum naming convention. The fact that "the other half of the programming world" does indeed use a different style makes me think it is legitimate to doubt our own religion.

Community
  • 1
  • 1
StaticNoiseLog
  • 1,221
  • 16
  • 24
  • 7
    **TIL** that only Java or C# programmers are real programmers, and that their numbers are equal. #sarcasm – Mindwin May 08 '17 at 15:41
  • 18
    C# is an otherwise great language, but this is just plain silly. *Everything* is pretty much pascal case in C#, which is basically the same as having no naming conventions at all; you gain nothing by looking at a name. You can't tell if it's a class, method, property, etc. – Bassinator Feb 10 '18 at 17:20
  • 3
    Also, boolean is practically an enum, the instances are true and false, in lowercase. So yes, all caps is ugly. – Florian F Aug 18 '18 at 19:03
  • @FlorianF, do not confuse the primary type boolean with the class Boolean (https://docs.oracle.com/javase/7/docs/api/java/lang/Boolean.html). the class does use the uppercase convention – IvoC Dec 12 '18 at 12:53
28

As already stated, enum instances should be uppercase according to the docs on the Oracle website (http://docs.oracle.com/javase/tutorial/java/javaOO/enum.html).

However, while looking through a JavaEE7 tutorial on the Oracle website (http://www.oracle.com/technetwork/java/javaee/downloads/index.html), I stumbled across the "Duke's bookstore" tutorial and in a class (tutorial\examples\case-studies\dukes-bookstore\src\main\java\javaeetutorial\dukesbookstore\components\AreaComponent.java), I found the following enum definition:

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

According to the conventions, it should have looked like:

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

So it seems even the guys at Oracle sometimes trade convention with convenience.

beosign
  • 423
  • 5
  • 10
14

In our codebase; we typically declare enums in the class that they belong to.

So for your Fruit example, We would have a Fruit class, and inside that an Enum called Fruits.

Referencing it in the code looks like this: Fruit.Fruits.Apple, Fruit.Fruits.Pear, etc.

Constants follow along the same line, where they either get defined in the class to which they're relevant (so something like Fruit.ORANGE_BUSHEL_SIZE); or if they apply system-wide (i.e. an equivalent "null value" for ints) in a class named "ConstantManager" (or equivalent; like ConstantManager.NULL_INT). (side note; all our constants are in upper case)

As always, your coding standards probably differ from mine; so YMMV.

Jim B
  • 7,736
  • 10
  • 46
  • 75
  • 5
    I want to add that it seems like that object factories are nowadays named using plurals, for example `Lists` and `Maps`. In my opinion this is a good convention and I fully supports its more widespread usage. – Esko Jun 18 '10 at 13:07
  • Yeah, they're similar to my personal coding standards, but different to my workplace coding standards. We don't have many standards in place for work, so I'm trying to find a good document to use as a reference. –  Jun 18 '10 at 13:08
  • 8
    `Fruit.Fruits.Apple` is too verbose to me, literally breaking the DRY principle :-) I would prefer e.g. `Fruit.Type.APPLE`. – Péter Török Jun 18 '10 at 13:09
  • 2
    I don't like this approach. The way this is named, an Apple either is-a Fruits, or at the very least it's confusing since it's not clear that Apple is-not-a Fruit. I like Peter's Type example. At least then it's self documenting that APPLE is-a type-of fruit. Though this whole fruits example smells kind of rotten... – Mark Peters Jun 18 '10 at 13:17
  • 1
    I also don't like this. If 'Fruit' class represents a fruit (and it should) then what can 'Fruits' represent? If Fruit (the class) really is a class for dealing with Fruit then it should be renamed "FruitHandler' or 'FruitManager'. – DJClayworth Jul 16 '10 at 17:12
  • I concur with Mark & DJ: in your example it looks fine, but `Fruits fruits = Fruits.APPLE;` certainly does not. – Maarten Bodewes Nov 15 '11 at 22:53
7

They're still types, so I always use the same naming conventions I use for classes.

I definitely would frown on putting "Class" or "Enum" in a name. If you have both a FruitClass and a FruitEnum then something else is wrong and you need more descriptive names. I'm trying to think about the kind of code that would lead to needing both, and it seems like there should be a Fruit base class with subtypes instead of an enum. (That's just my own speculation though, you may have a different situation than what I'm imagining.)

The best reference that I can find for naming constants comes from the Variables tutorial:

If the name you choose consists of only one word, spell that word in all lowercase letters. If it consists of more than one word, capitalize the first letter of each subsequent word. The names gearRatio and currentGear are prime examples of this convention. If your variable stores a constant value, such as static final int NUM_GEARS = 6, the convention changes slightly, capitalizing every letter and separating subsequent words with the underscore character. By convention, the underscore character is never used elsewhere.

Bill the Lizard
  • 369,957
  • 201
  • 546
  • 842
3

If I can add my $0.02, I prefer using PascalCase as enum values in C.

In C, they are basically global, and PEER_CONNECTED gets really tiring as opposed to PeerConnected.

Breath of fresh air.

Literally, it makes me breathe easier.

In Java, it is possible to use raw enum names as long as you static import them from another class.

import static pkg.EnumClass.*;

Now, you can use the unqualified names, that you qualified in a different way already.

I am currently (thinking) about porting some C code to Java and currently 'torn' between choosing Java convention (which is more verbose, more lengthy, and more ugly) and my C style.

PeerConnected would become PeerState.CONNECTED except in switch statements, where it is CONNECTED.

Now there is much to say for the latter convention and it does look nice but certain "idiomatic phrases" such as if (s == PeerAvailable) become like if (s == PeerState.AVAILABLE) and nostalgically, this is a loss of meaning to me.

I think I still prefer the Java style because of clarity but I have a hard time looking at the screaming code.

Now I realize PascalCase is already widely used in Java but very confusing it would not really be, just a tad out of place.

Xennex81
  • 359
  • 2
  • 6
0
enum MyEnum {VALUE_1,VALUE_2}

is (approximately) like saying

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

so I guess the all caps is strictly more correct, but still I use the class name convention since I hate all caps wherever