What's difference between enums and final variables?

12,693

Solution 1

When you have an enum like

public enum MyEnum {
   FIRST_COSTANT, SECOND_CONSTANT;
}

What you actually have is

public class /* enum */ MyEnum extends Enum<MyEnum> {
    private Enum() {}
    public final static MyEnum FIRST_CONSTANT = new MyEnum() {};
    public final static MyEnum SECOND_CONSTANT = new MyEnum() {};    
    ... // methods     
}

So in that sense, yes, they are the same.

This is explained in the Java Language Specification here.

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. Each such field is also considered to be annotated by the same annotations as the corresponding enum constant. The enum constant is said to be created when the corresponding field is initialized.

Solution 2

The difference is that enums provide type safety.

Let's have this enum.

public enum MuEnum {
    FIRST("First"), SECOND("Second");

    private String value;

    MyEnum(String value) {
        this.value = value;
    }

    public String getValue() {
        return value;
    }
}

Consider the following example:

public void myMethod(MyEnum parameter) { .. }

Here, you can only pass MyEnum values (FIRST or SECOND), while if your method signature was:

public void myMethod(String parameter) { .. }

you would be able to pass an invalid parameter (some String which content is different than "First" or "Second").

Solution 3

There is a big difference: first, enum, is not a variable, it is a type. A final variable, say, an int, can have a single, preset value from among many possible values of int, while an enum variable (which could also be final) can have a value from a set that you declare when defining the enum.

Here is an example:

enum Color {Red, Green, Blue;}

The declaration above does not define a variable. It defines a set of values a variable of type Color could have, if you choose to declare one:

Color backgroundColor = Color.Red;

Now you have a non-final variable of an enumerated type Color. Its value can change, but it must be one of the three values defined as part of the enum.

In practice, you use an enum when you model a something with a fixed number of states, to which you would like to give a name. You could use one or more final variables for that, too, - in fact, this has been done a lot before enums were introduced. For example, Java's Calendar class uses static final int constants for the various parts of the date, where an enum would have worked better.

Solution 4

I think enums are not final because you can define an anonymous subclass for each field inside of the enum descriptor.

From the docs:

Enum types (§8.9) must not be declared abstract; doing so will result in a compile-time error.

An enum type is implicitly final unless it contains at least one enum constant that has a class body.

It is a compile-time error to explicitly declare an enum type to be final.

Nested enum types are implicitly static. It is permissible to explicitly declare a nested enum type to be static.

Also to mark a point that if we say a class as Final then it means that they can not be inherited. However, when it comes to enums then they can not be inherited by default.

Solution 5

In one way of thinking, yes. The following statements are roughly equivalent:

// This...
final int FIRST = 0;
final int SECOND = 1;

// Is roughly equivalent to this.
enum Ordering = { FIRST, SECOND };

The difference is type safety. Since the Ordering enum names a new type, you can have a function which takes an Ordering rather than an int. This ensures at compile time that you don't accidentally pass an out of bounds value (like 2) to a function expecting an Ordering.

void foo(Ordering order) {;}

foo(FIRST); // This works
foo(3); // This causes an error at compile time
Share:
12,693

Related videos on Youtube

Marc Rasmussen
Author by

Marc Rasmussen

SOreadytohelp Website

Updated on September 14, 2022

Comments

  • Marc Rasmussen
    Marc Rasmussen over 1 year

    I am trying to read up on enums to better understand them.

    From the javadocs of enums I get the following:

    An enum type is a special data type that enables for a variable to be a set of predefined constants.

    To me this sounds a lot like a final variable.

    1. What is the real difference?
    2. And when would you use one over the other?
    3. Is enum just a final variable that can be a set of things?
  • msangel
    msangel over 10 years
    each enum entry is a subclass, not a just instance