Everything about enum data type in Java
Tags: java, enum, learning, details
Published: 2020-04-13 15:54:04

---
title: Everything about enum data type in Java
published: true
description: To let one know all about enum data type in Java
tags: java, enum, learning, details
---
The goal of this article is to expose one to the `enum` data type in `Java`. I hope by reading this one would learn something new or brush up their knowledge on `Java` `enum` data type. So, let’s dive in.

### The reason behind this article?
Well, I have been using enum without knowing essential knowledge about that. Recently, in an interview, I was asked, can an enum have a `constructor and instance variables`? I could not answer. The actual answer is yes. So, I decided to learn as much as I can on enum and share with others to let fall for the common pitfalls.

### What is the enum data type?
As by `javadoc` - 
> An enum type is a special data type that enables for a variable to be a set of predefined constants.

In other words, an enum data type is a set of constants and grouped together.

An enum is just class type as we create classes in Java but with a different special keyword `enum` and essentially do work as a simple Java class. All enum type implicitly extends `Enum` from `java.lang` package and can implement an `interface`(s) as well as an enum can have `constructors, instance variables and methods`. Every constant you defined in an enum will be `public static final` by default. Every enum constant has an index number called `ordinal` number. An ordinal number is just number that defines the position of that specific enum constant. The ordinal number starts with 0 as an array in most languages.

One VERY dangerous miss conception would be - if an enum can have a constructor then I can create an instance of an enum using the new keyword. NO - you CANNOT instantiate an enum type but wait then why would an enum have a constructor? I will answer that later in this article.

Let’s create a very basic enum type. Let’s take the measurement `Size` as an example of an enum. When a company makes clothes they define there own size of their clothes (yes, there are some standard sizes but let’s not think of that).
```Java
public enum Size
{
   SMALL,		// 0
   MEDIUM,		// 1
   LARGE,		// 2
  
   EXTRA_SMALL,		// 3
   EXTRA_EXTRA_SMALL,	// 4

  EXTRA_LARGE, 		// 5
  EXTRA_EXTRA_LARGE	// 6

}
```

All the Sizes defined inside `Size` are enum constants of type Size. 

As we can see that if we have more than one constants then they are separated by commas and the last one does not have any semicolon, although putting one at the end does not affect anything but it's mandatory when we use constructor and instance variables.

So, how do we access them? Since all constants are `implicitly public static final`, we can use the enum type - Size to access it.

```Java
Size small = Size.SMALL;
Size extraSmall = Size.EXTRA_SMALL;
System.out.println(small);
System.out.println(extraSmall);
``` 
will output - 

```Java
SMALL
EXTRA_SMALL
```

respectively to the console.

Wait! Hold on, `Size.EXTRA_SMALL` is going to need more space in our clothes, more ink means more cost. So, why not `symbolize` them to reduce all the overhead. To do that we are slightly going to refactor our enum - Size and that’s when we are going to use a contractor and an instance variable(s).

```Java
public enum Size
{
   SMALL("S"),          // 0
   MEDIUM("M"),         // 1
   LARGE("L"),          // 2
  
   EXTRA_SMALL("XS"),            // 3
   EXTRA_EXTRA_SMALL("XXS"),      // 4
  
   EXTRA_LARGE("XL"),            // 5
   EXTRA_EXTRA_LARGE("XXL");       // 6
  
   private final String value;
  
   Size(String value)
   {
       this.value = value;
   }
  
   public String getValue()
   {
       return value;
   }
}
```

Things to notice - a `final instance variable ‘value’`, an overloaded constructor with `implicit private access modifier`. `Public and protected are NOT allowed as they would allow you to instantiate`. And finally, a `getter` method to get the value of an enum constant.

Now, thanks to the instance variable, constructor, and getter method we can reduce our cost and print something like this - 

```Java
Size extraSmall = Size.EXTRA_SMALL;
Size extraExtraLarge = Size.EXTRA_EXTRA_LARGE;

System.out.println(extraSmall.getValue());
System.out.println(extraExtraLarge.getValue());
```
will output - 
```Java
XS
XXL
```
respectively to the console. 

A value can also be directly accessed/passed to others like
```Java
System.out.println(Size.MEDIUM.getValue());	 // M
```

Now, what if your company decides that not only we are going to display the `letters/symbol` of a Size, for customer convenience we will display the size in `inches` next to the Size letter/symbol. Well, no worries we won’t have to drastically change or create another enum for size. We can do so like this - 

```Java
public enum Size
{
   SMALL("S", 6),          // 0
   MEDIUM("M", 8),         // 1
   LARGE("L", 10),          // 2
  
   EXTRA_SMALL("XS", 4),            // 3
   EXTRA_EXTRA_SMALL("XXS", 2),      // 4
  
   EXTRA_LARGE("XL", 12),            // 5
   EXTRA_EXTRA_LARGE("XXL", 14);       // 6
  
   private final String value;
   private final int inches;
  
   Size(String value, int inches)
   {
       this.value = value;
       this.inches = inches;
   }
  
   public String getValue()
   {
       return value;
   }
  
   public int getInches()
   {
       return inches;
   }
}
```
Now a Size enum instance has 2 attributes called value and inches.

### What about `Ordinal` number and other types of `methods`?

Let’s start with the ordinal number. As mentioned the ordinal number is nothing but the position of the constants. Let’s organize our Size constants from smallest to largest by inches.

```Java
...
EXTRA_EXTRA_SMALL("XXS", 2),      // 0
EXTRA_SMALL("XS", 4),            // 1
SMALL("S", 6),          // 2
MEDIUM("M", 8),         // 3
LARGE("L", 10),          // 4
EXTRA_LARGE("XL", 12),            // 5
EXTRA_EXTRA_LARGE("XXL", 14);       // 6
...
```

Everything else is the same. To get the ordinal number/index number of an enum constant Size - 
```Java
System.out.println(Size.MEDIUM.ordinal()); 
```
Will print `3` to the console as `MEDIUM` in the `4` positions.
The `ordinal()` is a method available to `Size instance`. 

There are 2 important methods available to the enum type Size along with others. They are called `valueOf(string)` and `values()`.

`values()` return an array of enum type ex. Size and since it returns an array we can index it or iterate it, as by our needs.

```Java
System.out.println(Size.values()[0]); // EXTRA_EXTRA_SMALL

System.out.println(Size.values().length); // 7
```

And `Size.valueOf(“string”)` will take a string argument and will return an instance of that enum type ex. `Size` that has the same name as “string”, if not found by the name then `IllegalArgumentException` will the thrown.

More rarely, an enum type can also have `abstract methods`.

```Java
public enum Size
{
   EXTRA_EXTRA_SMALL("XXS", 2){
       @Override
       public String formatMyWay()
       {
           return EXTRA_EXTRA_SMALL.getValue()+" - " + EXTRA_EXTRA_SMALL.getInches() + "\"";
       }
   };
  
   public abstract String formatMyWay();
  
   // everything else is the same as before
}
```
Well, that’s all about enum from my end. I hope this was helpful and if I missed something please feel free to collaborate. Happy coding!

## References: 
[JavaDoc](https://docs.oracle.com/javase/tutorial/java/javaOO/enum.html)
[Oracle Java Tutorial](https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html)