Skip to content

Enum in Java

Enum in java is a data type which contains a fixed set of constants. In enum, we can also add variables, methods and constructors. Some common examples of enums are: days of week, colors, excel report columns etc.

Enum Characteristics

  • enum constants are static and final implicitly

  • enum improves type safety

  • num can be declared inside or outside of a class

  • enum can have fields, constructors (private) and methods

  • enum cannot extend any class because it already extends Enum class implicitly but it can implement many interfaces

  • We can use enum in switch statement

  • We can have main() method inside an enum

  • enum has values(), ordinal() and valueOf() methods.

    values() return an array containing all values present inside enum, ordinal() method returns the index of given enum value and valueOf() method returns the value of given constant enum

  • enum can be traversed

  • enum can have abstract methods

  • enum cannot be instantiated because it contains private constructor only

  • The constructor is executed for each enum constant at the time of enum class loading

  • While defining enum, constants should be declared first, prior to any fields or methods, or else compile time error will come

Abstract Method in Enum

We can define an abstract method in an enum, and let each enum constant to implement it, let's look at an example.

Java
public enum EnumAbsMethod {
    A("a"){
        @Override
        String getValue() {
            return "A";
        }
    }, B("b"){
        @Override
        String getValue() {
            return "B";
        }
    };

    EnumAbsMethod(String val) {
        this.value = val;
    }
    String value;

    abstract String getValue();

    public static void main(String[] args) {
        for (var en : EnumAbsMethod.values()) {
            System.out.println(en.getValue());
        }

    }
}

The output:

Text Only
A
B

Implement Interface

We can define an interface, and let the enum to implement the interface.

  • the enum can implement the interface method in enum class, or

  • let the each constant to implement the interface method

Let's look at the example.

Java
interface StringOperation {
    String getDescription();
    String apply(String input);
}

public enum EnumImpInterface implements StringOperation {
    Trim("trim string") {
        @Override
        public String apply(String input) {
            return input.trim();
        }
    }, Reverse("reverse string") {
        @Override
        public String apply(String input) {
            return new StringBuilder(input).reverse().toString();
        }
    };

    String desc;

    EnumImpInterface(String desc) {
        this.desc = desc;
    }


    @Override
    public String getDescription() {
        return desc;
    }

    public static void main(String[] args) {
        var strArr = Arrays.asList(" abc ", " bdc");
        for (var str : strArr) {
            for (StringOperation strOp : EnumImpInterface.values()) {
                System.out.println(String.format("origin: '%s', apply '%s'->'%s'", str, strOp.getDescription(), strOp.apply(str)));
            }
        }
    }
}

The output:

Text Only
origin: ' abc ', apply 'trim string'->'abc'
origin: ' abc ', apply 'reverse string'->' cba '
origin: ' bdc', apply 'trim string'->'bdc'
origin: ' bdc', apply 'reverse string'->'cdb '

How to extend an enum without changing the enum

Sometimes, we may want to extend an enum which is provided by third-party library. Hence, we can't change the source code, but we still can extend it in the following way.

Let's look at the example.

Java
import java.util.Arrays;
import java.util.EnumMap;
import java.util.Map;

// third-party enum
enum ThirdPartyEnum {
    Trim, Reverse;
}

interface EnumStrOperator {
    String apply(String input);
}

public class EnumExt {
    private static final Map<ThirdPartyEnum, EnumStrOperator> ENUM_OP_MAP = new EnumMap<>(ThirdPartyEnum.class);

    static {
        ENUM_OP_MAP.put(ThirdPartyEnum.Trim, String::trim);
        ENUM_OP_MAP.put(ThirdPartyEnum.Reverse, input -> new StringBuilder(input).reverse().toString());
    }

    public String applyThirdPartyEnumOp(ThirdPartyEnum en, String input) {
        return ENUM_OP_MAP.get(en).apply(input);
    }

    public static void main(String[] args) {
        var app = new EnumExt();

        var strArr = Arrays.asList(" abc ", " bdc");

        for (var str : strArr) {
            for (var en : ThirdPartyEnum.values()) {
                System.out.println(String.format("origin: '%s', apply '%s'->'%s'", str, en.name(), app.applyThirdPartyEnumOp(en, str)));
            }
        }

    }
}

The output:

Text Only
origin: ' abc ', apply 'Trim'->'abc'
origin: ' abc ', apply 'Reverse'->' cba '
origin: ' bdc', apply 'Trim'->'bdc'
origin: ' bdc', apply 'Reverse'->'cdb '