Tuesday, 13 September 2016

Java Enum

The purpose of using enum is to constrain user inputs from a limited set of instances. 

Implicitly, Enum is a final class that extends from a Java abstract Enum class.  The enum has some implicit operations done by java compiler.  The compiler adds a static block in order to initialise all public static constants. By default, the enum class inherits a two-argument constructor from its superclass, and it includes the name and ordinal of the constant. Enum name() and toString() gives the same values, and Enum instance is ordered by its definition, and thereby constants cannot be sorted by an external sorting algorithm. 

Java enum cannot extend from other classes; for it implicitly extends abstract java.lang.Enum class. However, a Java enum can implement many interfaces. Java enum cannot be extended, because it is defined as a final class implicitly. 

Enum name(), hashCode() method is a final method, but toString() is not, so toString is allowed to be overridden. 

the enum allows adding extra attributes for each constant.
the enum allows private or default-access level constructors.
the enum cannot define constructors with a public or protected access level.
the enum allows set/get methods to access extra attributes on each constant.

An enum can define an abstract method. just ensure to override it for all your enum constants.
The enum method values are initialised in its super-class static block, it contains all defined enum constants.

Constants may not be followed by a semicolon if there is no other variables or methods defined inside this enum body. 

Here I created a simple example, which defines all directions, i.e. east, west, south, north; and I give each direction an extra attribute, i.e. degree. It can be initialized by its private constructor.

The following example shows that Enum value and attributes can be initialized by its constructors.
The toString() method can be overridden; it offers a convenient way to show each value and its attributes by one kick. 

One interesting thing, when I use Enum in the switch body, it doesn't need Enum identifier to refer to its own values. I guess the java compiler is becoming smarter and smarter. It can infer from switch input argument type itself. Once it finds an Enum type, then it will ignore the Enum identifier.

A constant specific class body defines overriding methods for a particular enum constant. 

Where can you define an enum? 
Enum can be independent, or a member of a class or an interface. However, Enum cannot be local within a method.



/*
 * In Java, Enum is a class type. 
 * 
 * 
 */
package Enum;

import java.util.Arrays;

/**
 *
 * @author YNZ
 */
public enum Direction {
    EAST(10), SOUTH(20), WEST(40), NORTH(30);
    
    //Enum constructor must be private or pakage-private(default access modifier)
    private Direction(double degree) {
        this.degree = degree;
    }

    private Direction() {
        this.degree = 0;
    }

    public static Direction getEAST() {
        return EAST;
    }

    public static Direction getNORTH() {
        return NORTH;
    }

    public static Direction getWEST() {
        return WEST;
    }

    public double getDegree() {
        return degree;
    }

    public static Direction getSOUTH() {
        return SOUTH;
    }

    @Override
    public String toString() {
        return this.name() + " " + this.getDegree();
    }
    
    //init. once as it is contructed. 
    private final double degree;
}


class UsingEnum {

    public static void main(String[] args) {
        System.out.println(Direction.EAST);
        Direction d = Direction.valueOf("EAST");
        System.out.println("" + d);
        System.out.println(Arrays.toString(Direction.values()));
        
        tellDirection(Direction.EAST);
        tellDirection(Direction.NORTH);
        
        //adding get method to return client attribute. 
        System.out.println(""+Direction.EAST.getDegree());
        
        //how to traverse Enum members by a loop
        for(Direction direction: Direction.values()){
            System.out.println(direction.name() + " " +direction.getDegree());
        }
        //overriding toString() to print out enum member properties.
        System.out.println(" "+ Arrays.toString(Direction.values()));
                
        
    }

    public static void tellDirection(Direction direction) {
        //Enum value can be inferred without using identifier. 
        switch (direction) {
            case EAST:
                System.out.println("Goto East.");
                break;
            case SOUTH:
                System.out.println("Goto South");
                break;
            case WEST:
                System.out.println("Goto West");
                break;
            case NORTH:
                System.out.println("Goto North");
                break;
            default:
                System.out.println("Goto no where");

        }

    }
}


No comments:

Can Jackson Deserialize Java Time ZonedDateTime

Yes, but must include JSR310. Thus ZonedDateTime can be deserialized directly from JSON response to POJO field. <dependency> <g...