Course topics

By WebNest Studio Engineering Team

Advanced Java Tutorial

Enums in Java

An enum (short for enumeration) is a special Java type that represents a fixed set of named constants — think days of the week, directions, or order statuses. Unlike a plain set of int or String constants, an enum in Java is a full class: it can have its own constructor, fields, and methods, and every enum implicitly extends java.lang.Enum.

Because enum values are known and fixed at compile time, the compiler can catch mistakes that plain constants cannot — passing an invalid value simply cannot happen, because no such enum constant exists to pass. This makes enums one of the simplest ways to make Java code both safer and more self-documenting.

Why it matters

Order statuses, user roles and plan types have a fixed set of values, and representing them as strings or integers invites typos and invalid values that the compiler cannot catch. Java enums are full classes, so each constant can carry data and behaviour, which removes a great many if chains.

Enums as Special Classes

Declaring enum Day { MONDAY, TUESDAY, ... } creates a class with exactly those named, singleton instances — Day.MONDAY is not just a label, it is a real object, and it is always the same object every time it's referenced (enum constants are inherently singletons and safe to compare with ==). Every enum automatically inherits useful methods: name() returns the constant's exact declared name, and ordinal() returns its position (starting at 0) in the declaration.

Adding Fields, Constructors, and Methods

Enums become genuinely powerful once you attach data and behavior to each constant. You give the enum a private field and a constructor, and then supply constructor arguments after each constant's name. Each constant can also override methods individually if needed, but most commonly they share methods defined once on the enum type, using each constant's own field values.

values(), valueOf(), and switch

Every enum automatically gets a static values() method that returns an array of all constants in declaration order — ideal for looping over every possible value. valueOf(String) converts a matching String back into the corresponding constant, throwing IllegalArgumentException if the name doesn't match exactly. Enums also work naturally in a switch statement or expression, where you reference the bare constant name (without the enum type prefix) in each case label.

  • EnumType.values() — returns all constants as an array, in declaration order.
  • EnumType.valueOf("NAME") — parses a String into the matching constant, or throws if none matches.
  • constant.name() and constant.ordinal() — the declared name and zero-based position.

Examples

A basic enum used with switch, values(), and valueOf()

Java
public class EnumBasicsDemo {

    enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }

    static boolean isWeekend(Day day) {
        switch (day) {
            case SATURDAY:
            case SUNDAY:
                return true;
            default:
                return false;
        }
    }

    public static void main(String[] args) {
        Day today = Day.SATURDAY;
        System.out.println(today + " is weekend: " + isWeekend(today));

        for (Day d : Day.values()) {
            System.out.print(d.ordinal() + ":" + d + " ");
        }
        System.out.println();

        Day parsed = Day.valueOf("FRIDAY");
        System.out.println("Parsed: " + parsed);
    }
}
Output
SATURDAY is weekend: true
0:MONDAY 1:TUESDAY 2:WEDNESDAY 3:THURSDAY 4:FRIDAY 5:SATURDAY 6:SUNDAY
Parsed: FRIDAY

An enum with fields, a constructor, and a method per constant

Java
public class EnumWithFieldsDemo {

    enum Planet {
        MERCURY(3.303e+23, 2.4397e6),
        VENUS(4.869e+24, 6.0518e6),
        EARTH(5.976e+24, 6.37814e6);

        private final double mass;   // kilograms
        private final double radius; // meters

        Planet(double mass, double radius) {
            this.mass = mass;
            this.radius = radius;
        }

        double surfaceGravity() {
            final double G = 6.67300E-11;
            return G * mass / (radius * radius);
        }
    }

    public static void main(String[] args) {
        for (Planet p : Planet.values()) {
            System.out.printf("%-8s gravity: %.2f m/s^2%n", p, p.surfaceGravity());
        }
    }
}
Output
MERCURY  gravity: 3.70 m/s^2
VENUS    gravity: 8.87 m/s^2
EARTH    gravity: 9.80 m/s^2

Common Mistakes

  • Using plain int constants (e.g. public static final int MONDAY = 0) instead of an enum, which allows any invalid int to be passed where only a fixed set of values makes sense.
  • Calling valueOf() with a name that doesn't exactly match a declared constant (including case) and not handling the resulting IllegalArgumentException.
  • Comparing enum constants with .equals() out of habit — == is both safe and idiomatic for enums, since each constant is a single shared instance.
  • Forgetting the semicolon after the last constant when an enum also declares fields, constructors, or methods below it.

Exercise

Define an enum Plan with the constants FREE, PRO and TEAM, each holding a monthly price of 0, 499 and 1999, and a method yearly() that returns twelve times the price. Print the yearly price of the plan named by the string PRO, then the name and monthly price of every plan that is not free.

Expected output: 5988, PRO 499, TEAM 1999 (one per line)

Java · starter code
// TODO: enum Plan with a price field, a constructor and yearly()

public class Plans {
    public static void main(String[] args) {
        // TODO: look up the plan named "PRO" and print its yearly price

        // TODO: loop over all plans, printing "NAME price" for those with a price above 0
    }
}
Show hints
  • Each constant passes its data to the constructor: PRO(499). An enum constructor is implicitly private.
  • Plan.valueOf("PRO") returns the constant with that name, and Plan.values() returns all of them in declaration order.
Show solution
Java · solution
enum Plan {
    FREE(0),
    PRO(499),
    TEAM(1999);

    private final int price;

    Plan(int price) {
        this.price = price;
    }

    int price() {
        return price;
    }

    int yearly() {
        return price * 12;
    }
}

public class Plans {
    public static void main(String[] args) {
        System.out.println(Plan.valueOf("PRO").yearly()); // 5988

        for (Plan plan : Plan.values()) {
            if (plan.price() > 0) {
                System.out.println(plan + " " + plan.price()); // PRO 499, TEAM 1999
            }
        }
    }
}

Quick quiz

1. What does Plan.valueOf("GOLD") do when no such constant exists?

  • A. Returns null
  • B. Returns the first constant
  • C. Creates a new constant
  • D. Throws IllegalArgumentException
Show answer

D. Input from outside should be checked or the exception caught.

2. How should two enum values be compared?

  • A. With ==, since each constant exists exactly once
  • B. Only with equals()
  • C. By comparing their names as strings
  • D. With compareTo only
Show answer

A. == is also safe when one side is null, where equals() would throw.

3. Why is storing ordinal() in a database a bad idea?

  • A. It is slow
  • B. The number changes if constants are reordered or one is inserted, silently changing the meaning of stored data
  • C. It is not allowed
  • D. It returns a string
Show answer

B. Store the name, or an explicit code held in a field.

Interview questions

Why use an enum instead of constants such as public static final int?

Show answer

Integer or string constants are not type-safe: a method that takes an int status accepts any number. An enum is its own type, so only its constants can be passed, and the compiler checks it. Enums print with readable names, can be listed with values(), work in switch, and can carry fields and methods. They are also guaranteed singletons, so they can be compared with ==.

Can an enum have fields, methods and implement interfaces?

Show answer

Yes. An enum is a class: it can declare fields, a constructor that each constant calls with its own arguments, and methods. A constant can even supply its own body for a method, giving behaviour that differs per constant. An enum can implement interfaces but cannot extend a class, because it already extends java.lang.Enum, and it cannot be instantiated with new.

Key Points to Remember

  • An enum is a special class with a fixed set of singleton instances, not just a group of int or String constants.
  • Enums can have constructors, fields, and methods, letting each constant carry its own data and behavior.
  • values() lists all constants in order; valueOf(String) parses a name back into a constant.
  • Enums are safer than int constants because the compiler guarantees only a valid, declared constant can ever be used.

Practice in the playground

Write and run your own code for this topic, or start from the exercise or an example. Runs plain Java 17. Frameworks such as Spring, and databases, are not available here. Your code for each topic is kept in this browser.

Run the examples

Change an input, predict the result, then compare it with the output. Explain why the result changes.

These examples need a JDK project with their libraries on your computer, so they can be copied but not run here. Codelab runs Python, FastAPI backends with SQLite, plain Java 17 and HTML/CSS/JavaScript.

WebNest Studio

Written by

WebNest Studio Engineering Team

Practical lessons from developers working with Java, Python, React, databases and production systems.

Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering