Enums

0

An enum type is a special data type containing a set of predefined constants. Each enumerated value is of the same type as the type containing it. For example:

SimpleLengthEnum defines length units.

package javarticles.enums;

public enum SimpleLengthEnum {
    CM, MM, M
}

Because they are constants, the names of an enum type’s fields are in uppercase letters.
The enumdeclaration defines a class (called an enum type). where each enum value defined belongs to the same type containing it.

    
    public void testEnums() {
        assertTrue(SimpleLengthEnum.CM instanceof Object);
        assertTrue(SimpleLengthEnum.CM instanceof SimpleLengthEnum);
        assertTrue(SimpleLengthEnum.CM.getClass() == SimpleLengthEnum.class);
    }

Enums can have methods and fields

The enum class body can include methods and other fields.
For example, the below LengthEnum contains method convert(value, lengthEnum) to convert the length from one unit to another.

package javarticles.enums;

import java.util.HashMap;
import java.util.Map;

public enum LengthEnum {
    CM("Centimeter"),
    MM("Millimeter"),
    M("Meter");
    
    private LengthEnum(String name) {
        this.name = name;
    }

    public int convert(int value, LengthEnum lengthEnum) {
        if (lengthEnum == this) {
            return value;
        }
        Map<LengthEnum, Double> conversionFactors = conversion.get(this);
        if (conversionFactors == null) {
            throw new RuntimeException("conversion factors map missing for "
                    + this);
        }
        Double factor = conversionFactors.get(lengthEnum);
        if (factor == null) {
            throw new RuntimeException("conversion factor missing for "
                    + this+ "/" + lengthEnum);
        }
        return (int) (factor * (double)value);
    }

    private static final Map<LengthEnum, Map<LengthEnum, Double>> conversion = new HashMap<>();
    static {
        Map<LengthEnum, Double> cmConversionFactors = new HashMap<LengthEnum, Double>();
        cmConversionFactors.put(LengthEnum.MM, 10d);
        cmConversionFactors.put(LengthEnum.M, 0.01d);
        conversion.put(LengthEnum.CM, cmConversionFactors);
        
        Map<LengthEnum, Double> mmConversionFactors = new HashMap<LengthEnum, Double>();
        mmConversionFactors.put(LengthEnum.M, 0.001d);
        mmConversionFactors.put(LengthEnum.CM, 0.1d);
        conversion.put(LengthEnum.MM, mmConversionFactors);
        
        Map<LengthEnum, Double> mConversionFactors = new HashMap<LengthEnum, Double>();
        mConversionFactors.put(LengthEnum.CM, 100d);
        mConversionFactors.put(LengthEnum.MM, 1000d);
        conversion.put(LengthEnum.M, mConversionFactors);
    }
    
    public String getName() {
        return name;
    }
    
    private String name;
}

Here is the test case that converts length from one unit to another:

    public void testLengthEnum() {        
        assertEquals(100, LengthEnum.M.convert(1, LengthEnum.CM));
        assertEquals(1, LengthEnum.CM.convert(100, LengthEnum.M));
        assertEquals(1, LengthEnum.MM.convert(1000, LengthEnum.M));
        assertEquals(1, LengthEnum.MM.convert(10, LengthEnum.CM));
    }

Enum’s Constructor

You cannot invoke an enum's constructor directly. The enum constructor is invoked automatically, with the arguments you define after the constant value.

For example, CM(“Centimeter”), invokes private LengthEnum(String name).

The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared.

    public void testEnumValues() {
        for (SimpleLengthEnum length : SimpleLengthEnum.values()) {
            System.out.println(length);
        }
    }

Output

CM
MM
M

If you notice, we haven’t overridden toString() but still it prints the enum name. This is because every enum typ extends java.lang.Enum (implicitly of course). Enum class has already overridden toString() to return the name.

    public void testEnumExtendsJavaLangEnum() {
        System.out.println(SimpleLengthEnum.CM instanceof java.lang.Enum);
    }

Summary of enum type

  1. An enum is an immutable object and one can compare enums using == operator.
  2. You can’t extend an enum.
  3. Emum can implement an interface, this way you can make use of polymorphism.
  4. One can add behavior to enums just like classes.
  5. You can iterate through the enum values in the order in which they are defined.
  6. The constructor for an enum type must be package-private or private access. You cannot invoke an enum constructor yourself.
  7. It automatically creates the constants that are defined at the beginning of the enum body.
  8. The behavior of constructor is similar to class, you can overload constructors. You can define constructors that take more than one argument.
  9. All enums implicitly extends java.lang.Enum.

Download the source code

I have shown you how an enum type works with some examples. Download enums.zip

About Author

Ram’s expertise lies in test driven development and re-factoring. He is passionate about open source technologies and loves blogging on various java and open-source technologies like spring.
You can reach him at [email protected]

Leave A Reply