Enum as instance variables

40,832

Solution 1

In

enum Coffee {
    BIG,
    SMALL
}

BIG or SMALL are public static final fields of Coffee class, and like all static fields they can be accessed by class name like

Coffee b1 = Coffee.BIG;

or by reference of same type as class, like

Coffee s2 = b1.SMALL;
Coffee s3 = Coffee.BIG.SMALL; //BIG is reference of type Coffee so it is OK (but looks strange)

But lets remember that we should avoid accessing static members via references. This creates confusion since we are not really accessing members of instance but members of class (so for instance there is no polymorphic behaviour).

Solution 2

This is what happens behind the scenes :

E:\workspace>type Coffee.java
public enum Coffee {
    BIG,
    SMALL
}

E:\workspace>javap Coffee
Compiled from "Coffee.java"
public final class Coffee extends java.lang.Enum<Coffee> {
  public static final Coffee BIG;
  public static final Coffee SMALL;
  public static Coffee[] values();
  public static Coffee valueOf(java.lang.String);
  static {};
}

As you can see BIG and SMALL are essentially static fields in your enum.

The JLS also make this part clear :

In addition to the members that an enum type E inherits from Enum, for each declared enum constant with the name n, the enum type has an implicitly declared public static final field named n of type E. These fields are considered to be declared in the same order as the corresponding enum constants, before any static fields explicitly declared in the enum type. Each such field is initialized to the enum constant that corresponds to it.

Hope this clarifies your question.

Solution 3

Before Java 5 the way to implement enums was to create a class with private constructor and public final fields of the same class initialised to specific values.

Since Java 5, enum construct is effectively a sugar that does the same, and takes care of things like null values are not allowed, enum values become public static fields etc.

Share:
40,832
LuckyLuke
Author by

LuckyLuke

Updated on July 05, 2022

Comments

  • LuckyLuke
    LuckyLuke almost 2 years

    If you have an enum such as

    enum Coffee {
        BIG,
        SMALL
    }
    

    and a class that has an instance variable like this of the enum:

    public class MyClass {
        private Coffee coffee;
    
        // Constructor etc.
    }
    

    Why is it possible in the constructor to say e.g. coffee.BIG? I don't understand that you can use the reference? Is enum as instance variables initialized to something other than null? It is the self test question #4 in the SCJP book in the first chapter. I tried to shorten the code and question.