What will you build

You will build a small application that will use Enum as one of the field of a class.

What You'll Learn

What will you need

In many situation (life or programming), you have variables that can only hold a finite numbers of values. For example, when you answer to a questions such as civil status, you have only a finite number of possibilities: Single, Divorced, Widowed, Married, Civil Partnership, Legally separated.

Of course, this depends of the country this question will be asked. But for the sake of this exercise, let's imagine that all the countries have the same civil status.

To enumerate this finite set of values, Java have a special type the Enum, this have been added in Java 5. To declare an enum, we need to use the keyword enum in the declaration of the class, followed by the name of the enum class, followed by the curly bracket.

We declare all the possible values, it doesn't need to be all in upper case, but this is the part of the Java convention to declare Enum and constant all in uper case. All the values are separated with a comma.

public enum CivilStatus {SINGLE, MARRIED, DIVORCED, WIDOWED, CIVIL_PARTERNSHIP, LEGALLY_SEPARATED}

Enum is in fact an abstract class and this class extends the class Object, as all classes in Java. The value of the enumeration are the only instances possible of this class. As all classes, the name of the file needs to be the same that the name of the Enum, in this case CivilStatus.java.

We can declare a enum inside a class or outside of the class, but if you declare an enum inside a class, it will only be accessible from this class.

As these are instance of classes, we can use the "==" to compare the value of two instance.

Documentation on Enum

To see how to use a enum we will create a small class that will use a enum that will enumerate the Duration of leaves for a tree.

public enum DurationLeaves{DECIDUOUS,EVERGREEN,MARCESCENT,FUGACIOUS}

And the class Tree

public class Tree {
    String commonName;
    String scientificName;
    DurationLeaves duration;

    public Tree (String commonName, String scientificName, DurationLeaves duration) {
        this.commonName = commonName;
        this.scientificName = scientificName;
        this.duration = duration;
    }

    @Override
    public String toString () {
        return "Tree{" +
                "commonName='" + commonName + '\'' +
                ", scientificName='" + scientificName + '\'' +
                ", duration=" + duration +
                '}';
    }
}


And the class to test this Tree Class, as you can see, for the DurationLeaves, when the Tree class is instantiate, the third parameter is given by writing the name of the class followed by a "." and followed by the value we want to assign.

public class TreeTest {
    public static void main (String[] args) {
        Tree larch = new Tree("larch","larix decidua", DurationLeaves.DECIDUOUS);
        Tree spruce = new Tree("Norway spruce","Picea abies", DurationLeaves.EVERGREEN);

        System.out.println(larch.toString());
        System.out.println(spruce.toString());
    }
}

Some methods are already defined in the abstract class Enum that we can use and invoke on any instance of a Enum type.

The method is the method valueOf(), which will take as a parameter a String. It will return the Enum value given that is related to the String value.

public class TreeTest {
    public static void main (String[] args) {
        Tree larch = new Tree("larch","larix decidua", DurationLeaves.DECIDUOUS);
        Tree spruce = new Tree("Norway spruce","Picea abies", DurationLeaves.EVERGREEN);

        System.out.println(larch.toString());
        System.out.println(spruce.toString());

        DurationLeaves deciduous = DurationLeaves.valueOf("DECIDUOUS");
        System.out.println(deciduous.toString());
    }
}

However, the String needs to be exactly the same than the value.

The method value will return all the values of the class Enum in an array of the type of the Enum. In this example, an array of DurationLeaves.

public class TreeTest {
    public static void main (String[] args) {
        Tree larch = new Tree("larch","larix decidua", DurationLeaves.DECIDUOUS);
        Tree spruce = new Tree("Norway spruce","Picea abies", DurationLeaves.EVERGREEN);

        System.out.println(larch.toString());
        System.out.println(spruce.toString());

        DurationLeaves deciduous = DurationLeaves.valueOf("DECIDUOUS");
        System.out.println(deciduous.toString());

        DurationLeaves[] values = DurationLeaves.values();
        for(DurationLeaves d : values){
            System.out.println(d.toString());
        }
    }
}

Other methods exist and could be invoke on an Enum instance: ordinal(), compareTo(), toString()

Documentation on Enum

When it is needed, it is possible to implement a private constructor that will allow the developper to associate another property to the Enum. For example, for the DurationLeaves, we could had a String to the Enum. For example, we could have a very small definition of the term.

public enum DurationLeavesBigger {

    DECIDUOUS("Leaf fall"),EVERGREEN("leaf never fall"),MARCESCENT("leaf dead"),FUGACIOUS("leaf very short life");

    private String def ;

    private DurationLeavesBigger(String def) {
        this.def = def ;
    }

    public String getDef() {
        return  this.def ;
    }

}

In this Enum, we did implement a private constructor that takes one parameter that is a String, and one method that is to getter and will return this String. Enum doesn't accept a public constructor. As you can observe the "instantiation" of the Enum is inside the class itself, but has a particular syntax.

To test this enum. We can use the utility class EnumSet to return all the Enum in a Set as it have been implemented below.

public class TreeTest {
    public static void main (String[] args) {

        String abreviation = DurationLeavesBigger.DECIDUOUS.getDef();
        System.out.println(abreviation);
        
        EnumSet<DurationLeaves> enums = EnumSet.allOf(DurationLeaves.class);
        for(DurationLeaves d : enums){
            System.out.println(d.name());
        }
    }
}

You can find the code for this example in https://git.cardiff.ac.uk/ASE_GROUP_2020/code_for_codelabs.git