DEV Community

Sota
Sota

Posted on

Understanding Java Enums by Rebuilding One

Enum is just a class

Have you ever noticed that you can define an enum-like class without using the enum keyword, just like a normal class you write in everyday development?

If not, this article is worth a look!

What is an Enum?

An enum is a type that defines a fixed set of predefined, type-safe constants, optionally with behavior.

Enums were introduced in Java 5. Before that, developers implemented enum-like classes manually.

Let’s travel back to that time to better understand how enums actually work under the hood.

Code example

Basic enum

enum Fruit {
    APPLE,
    BANANA;
}
Enter fullscreen mode Exit fullscreen mode

Let’s start with a simple example. This defines a type Fruit with exactly two allowed instances: APPLE and BANANA.

Although Java provides the enum keyword, the core idea behind an enum is not magical.
It can be expressed using a regular class with a few strict rules.

public final class Fruit {
    public static final Fruit APPLE = new Fruit();
    public static final Fruit BANANA = new Fruit();

    private Fruit() {};
}
Enter fullscreen mode Exit fullscreen mode

APPLE and BANANA are both instances of the Fruit class. Each of them is a singleton, meaning there is exactly one instance per constant. In other words, only one APPLE object and one BANANA object ever exist in the JVM.
Because these instances are created as public static final fields and the constructor is private, no additional instances can be created.

Adding a property

Let's add a property.

public enum Fruit {
    APPLE(200),
    BANANA(150);

    private int price;

    private Fruit(int price) {
        this.price = price;
    }
}
Enter fullscreen mode Exit fullscreen mode

The equivalent code without the enum keyword is shown below.
Now we have a price property, and the constructor receives a value and assigns it to that property.

public final class Fruit {
    public static final Fruit APPLE = new Fruit(200);
    public static final Fruit BANANA = new Fruit(150);

    private int price;

    private Fruit(int price) {
        this.price = price;
    };
}
Enter fullscreen mode Exit fullscreen mode

Adding a method

Finally, let's add a method that returns the price with tax included.

public enum Fruit {
    APPLE(200),
    BANANA(150);

    private int price;

    private Fruit(int price) {
        this.price = price;
    }

    public double addTax() {
        return price + (price * 0.1); // add 10% taxes
    }
}
Enter fullscreen mode Exit fullscreen mode

The equivalent implementation using a regular class:

public final class Fruit {
    public static final Fruit APPLE = new Fruit(200);
    public static final Fruit BANANA = new Fruit(150);

    private int price;

    private Fruit(int price) {
        this.price = price;
    };

    public double addTax() {
        return price + (price * 0.1);
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

This demonstrates that an enum is fundamentally the same as a regular class, expressed using different syntax and enforced by the language. Each enum constant is a singleton instance, and the enum keyword exists to guarantee this pattern safely and conveniently.

Top comments (0)