Enums in java are more useful than you think.

Enums in java

Enums in java is a widely used feature and the common use case of Enum is to use it as a variable when there are few valid options that the variable can take. For example, if you need a variable to represent the day of the week. You can use an Enum for that.

public enum WeekDays{
  MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY,SUNDAY
}

Simply Enums are used as constant variables but in compared to most of the languages, Enums in Java is more powerful because Enums are full-featured classes in java .Meaning, Enum can do anything that you do with a standard Class. Here are a few things that you already do with Classes, which can be improved by using Enums.

Singleton implementation with Enum

There are few ways you can implement Singleton in java. Lazy Initialization is being one of the common ways of doing it.

public class Singleton {
 
  private static Singleton INSTANCE = null;
 
  private Singleton() {
  }
 
  public static Singleton getInstance() {
     if (INSTANCE == null) {
        INSTANCE = new Singleton();
     }
     return INSTANCE;
  }
}
 

If your class has some complicated logic, the above implementation can lead you to problems with serialization and deserialization. You will have to handle it properly. Otherwise, it will end up having two instances of the class and break the singleton behavior. 

Another problem is, an advanced user can use reflection and modify the access modifier of the constructor and create any number of objects.

Let’s see how we can implement singleton with Enum, which will address all the above problems.

public enum Singleton {
  INSTANCE;
}

Just three lines !!. The above code will handle all the problems mentioned above . Firstly Enums are inherently serializable, you don’t have to implement / handle serialization  . Secondly ,Reflection issue is not there too. This will guarantee that there will be only one instance of this class. Amazing, isn’t it?

Enums to implement polymorphic behavior

Imagine you want to implement basic math operations. The typical way of doing this would be defining an interface called Operation and implementing it to basic other operators such as Add, Subtract etc.

public interface Operation {
  public abstract int apply(int x,int y);
}

class Add implements Operation{

   @Override
   public int apply(int x, int y) {
      return x + y;
   }
}
class Subtract implements Operation{

   @Override
   public int apply(int x, int y) {
      return x + y;
   }
}class Multiply implements Operation{

   @Override
   public int apply(int x, int y) {
      return x + y;
   }
}class Divide implements Operation{

   @Override
   public int apply(int x, int y) {
      return x + y;
   }
}

Above implementation can be simplified and implemented using Enums as below.

public enum Operation {
  ADD {
     @Override
     public int apply(int x, int y) {
        return x + y;
     }
  },
  SUBTRACT {
     @Override
     public int apply(int x, int y) {
        return x - y;
     }
  },
  MULTIPLY {
     @Override
     public int apply(int x, int y) {
        return x * y;
     }
  },
  DIVIDE {
     @Override
     public int apply(int x, int y) {
        return x - y;
     }
  };

  public abstract int apply(int x, int y);
}

The above code can be further modified to use lambdas as below.

public enum Operation {
  ADD((x, y) -> x + y),
  SUBTRACT((x, y) -> x - y),
  MULTIPLY((x, y) -> x * y),
  DIVIDE((x, y) -> x / y);

  private IntBinaryOperator operator;

  Operation(IntBinaryOperator operator) {
     this.operator = operator;
  }

  public int apply(int x, int y) {
     return operator.applyAsInt(x, y);
  }
}



Leave a Reply

Your email address will not be published. Required fields are marked *