Java’s most comprehensive Enum explanation

onxy
7 min readJan 10, 2024

--

Note: In the article is using the Oracle JDK 1.8.

Studying

Enum is a data type in Java that has some of the characteristics of a collection, and can store multiple elements, but the storage object is limited and fixed.

Enum also has more common use scenarios, such as we need to express the gender (male, female), color (red, yellow, blue), day of the week (Monday, Tuesday…), seasons (spring, summer, autumn, winter), geographic location (east, west, west), and so on. Sunday), the four seasons (spring, summer, autumn, winter), geographic location (east, west, south, north), direction (front, back, left, right), etc., these scenes are very suitable for enum.

Java defines enums using the enum keyword. An enum with a class and an interface that is the same level is called an enum (notice that this is enum, not Enum).

An enum can be defined in two ways::

  1. The empty constructor, or default constructor

To build an enum, use the constructor; the Quarter enum is:

public enum Quarter {

SPRING,
SUMMER,
AUTUMN,
WINTER;
}

This is an enum; the context is as follows if we decompile the Quarter.class file using the IntelliJ IDEA decompile tool:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

public enum Quarter {
SPRING,
SUMMER,
AUTUMN,
WINTER;

private Quarter() {
}
}

This decompiling tool is IntelliJ IDEA; alternative decompiling tools, such Jad, are also available here.

Once downloaded, you can utilize the command:

jad Quarter.class

Next, retrieve the decompile file from the Quarter.class; the code resulting from the decompilation is:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Quarter1.java


//final class can't extend from it
public final class Quarter extends Enum
{

//static method
public static Quarter[] values()
{
return (Quarter[])$VALUES.clone();
}

public static Quarter valueOf(String name)
{
return (Quarter)Enum.valueOf(Quarter, name);
}

//private Constructor method, the i is the index
private Quarter(String s, int i)
{
super(s, i);
}

public static final Quarter SPRING;
public static final Quarter SUMMER;
public static final Quarter AUTUMN;
public static final Quarter WINTER;
private static final Quarter $VALUES[];

// init the variable in the static code block, and add the default index
static
{
SPRING = new Quarter("SPRING", 0);
SUMMER = new Quarter("SUMMER", 1);
AUTUMN = new Quarter("AUTUMN", 2);
WINTER = new Quarter("WINTER", 3);
$VALUES = (new Quarter[] {
SPRING, SUMMER, AUTUMN, WINTER
});
}
}

The decompile file reveals that an enum is actually a kind of class, but the JVM assisted in generating the code by adding the final keyword, the private Constructor function, and initializing the variable in the static code block, among other things.

2. The alternative definition of an enum.

The explanation above demonstrates that an enum is a class, allowing us to define member variables, methods, static methods, abstract methods, and parameterized constructors, among other things.
I’ll also construct a new Quarter enum in another package:

/**
* @author onxy
* @Description:
* @date 2024-01-10
*/
public enum Quarter {

SPRING("spring"),SUMMER("summer"),AUTUMN("autum"),WINTER("winter");

//the field name
private String name;

//enum constructors could only be private
/*private Quarter(String name) {
this.name = name;
}*/
//Although I haven't added the private keyword,
//the JVM will do so automatically.
Quarter(String name) {
this.name = name;
}

//get the name
public String getName() {
return name;
}

//set the name
public void setName(String name) {
this.name = name;
}

//create a public static method
public static void printSumerName(){
System.out.println(Quarter.SUMMER.name);
}
}

Note: Enum, like to classes, are capable of having several constructors. This means that, in addition to a parameterized constructor, an unparameterized constructor can also exist. The compilation process remains error-free.

In the Java, all the create enum have a parent, the father is java.lang.Enum, all enum is extend from the java.lang.Enum.

The code is blew, i have annotate the key elements:

Every create enum in Java has a father, and that father is java.lang.Enum. Every enum extends from the java.lang.Enum.List some code from java.lang.Enum, I’ve highlighted the essential components:

package java.lang;

import java.io.Serializable;
import java.io.IOException;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.ObjectStreamException;

// implements the Comparable and Serializable interface,
// could be used to campare
public abstract class Enum<E extends Enum<E>>
implements Comparable<E>, Serializable {

//the object name
private final String name;

//get the name
public final String name() {
return name;
}

//the object index
private final int ordinal;

//get the object index
public final int ordinal() {
return ordinal;
}
// this is a protect constructor method, with name and index
protected Enum(String name, int ordinal) {
this.name = name;
this.ordinal = ordinal;
}
// the equal method
public final boolean equals(Object other) {
return this==other;
}
// the override compareTo method
public final int compareTo(E o) {
Enum<?> other = (Enum<?>)o;
Enum<E> self = this;
if (self.getClass() != other.getClass() && // optimization
self.getDeclaringClass() != other.getDeclaringClass())
throw new ClassCastException();
return self.ordinal - other.ordinal;
}
}

Enum values have the public static final by default and are all constants. Since enum is a final class, it cannot be implemented or inherited by default;

A compilation issue happens if the enum value is not on the first line when creating a new one;
Get the blown context once I use Jad to decompile the new Quarter.class:

// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Quarter2.java

import java.io.PrintStream;

public final class Quarter extends Enum
{

public static Quarter[] values()
{
return (Quarter[])$VALUES.clone();
}

public static Quarter valueOf(String name)
{
return (Quarter)Enum.valueOf(Quarter, name);
}

private Quarter(String s, int i, String name)
{
super(s, i);
this.name = name;
}

public String getName()
{
return name;
}

public void setName(String name)
{
this.name = name;
}

public static void printName()
{
System.out.println(SUMMER.name);
}

//single instance for all object
public static final Quarter SPRING;
public static final Quarter SUMMER;
public static final Quarter AUTUMN;
public static final Quarter WINTER;
//the field
private String name;
private static final Quarter $VALUES[];

static
{
//init the object
SPRING = new Quarter("SPRING", 0, "spring");
SUMMER = new Quarter("SUMMER", 1, "summer");
AUTUMN = new Quarter("AUTUMN", 2, "autum");
WINTER = new Quarter("WINTER", 3, "winter");
$VALUES = (new Quarter[] {
//create a new Quarter array
SPRING, SUMMER, AUTUMN, WINTER
});
}
}

Thus, we describe the Java enum creation process.
I’ll demonstrate how to use the Java enum next.

  1. Get the enum object and field

public class Test {

public static void main(String[] args) {
//get enum object
System.out.println(Quarter.AUTUMN);
//requet toString() to turn it to String
System.out.println(Quarter.AUTUMN.name());
System.out.println(Quarter.AUTUMN.toString());
//get object field
System.out.println(Quarter.AUTUMN.getName());
//static method
Quarter.printName();
}
}

2. Iterate over the enum class

You must iterate by using the Quarter.values() method if you need to get every element from the enum as query conditions.

import java.util.ArrayList;
import java.util.List;


public class Test3 {
public static void main(String[] args) {
//by the values() method to get the Quarter element array
Quarter[] quarters = Quarter.values();
List<String> quarterParam = new ArrayList<>(quarters.length);
//add the element in the array to List
for (Quarter quarter : quarters) {
quarterParam.add(quarter.toString());
}
}
}

3. Use the enum in switch conditional judge

Although the enum’s components are constrained and fixed, the conditional judgment by switch is perfectly appropriate.

Quarter quarter = Quarter.AUTUMN;
switch (quarter) {
case SPRING:
System.out.println("get it, it's:" + Quarter.SPRING);
break;
case SUMMER:
System.out.println("get it, it's:" + Quarter.SUMMER);
break;
case AUTUMN:
System.out.println("get it, it's:" + Quarter.AUTUMN);
break;
case WINTER:
System.out.println("get it, it's:" + Quarter.WINTER);
break;
default:
System.out.println("not found");
break;
}

As the enum of natural type restrictions only allows you to pass elements and null, there is actually no need to set the content here to default, or to WINTER as the default.

However, in most cases, it will be determined in advance to pass the parameter as null, and java.lang. NullPointerException will be raised when a switch receives null.

4. Compare enum

Checking if two elements are equivalent.
As an instance of a non-class, non-instantiable object, the storage location will not naturally vary based on the object when enumerated to determine if two elements are equal with the use of ==.

//enum compare
System.out.println(Quarter.AUTUMN==Quarter.AUTUMN);//true
System.out.println(Quarter.AUTUMN.equals(Quarter.AUTUMN));//true
System.out.println(Quarter.AUTUMN==Quarter.SUMMER);//false
System.out.println(Quarter.AUTUMN.equals(Quarter.SUMMER));//false

Moreover, you may apply the compareTo method:

System.out.println(Quarter2.AUTUMN.compareTo(Quarter2.AUTUMN));//0
System.out.println(Quarter2.AUTUMN.compareTo(Quarter2.SUMMER));//1
System.out.println(Quarter2.SUMMER.compareTo(Quarter2.AUTUMN));//01

5. Enum implement the interface

public interface WeatherInterface {
//Getting the temperature
String getTemperature(Quarter quarter);

}


// create a new Enum implement WeatherInterface interface
enum QuarterNew implements WeatherInterface {
//There's a semicolon here.
;

@Override
public String getTemperature(Quarter2 quarter) {
return quarter.getName();
}
}

Keep in mind that a semicolon needs to be inserted here if no specific object is declared.

6. Using interfaces to organize enum

Interfaces can be used to group similar enum together for management purposes if there are too many enum to handle and the organization is not obvious enough.

public interface Weather {
enum Quarter implements Weather {
SPRING, SUMMER, AUTUMN, WINTER;
}
enum Temperature implements Weather {
MODERATE, HEAT, COOL, COLD
}
//The call method is made directly through Weather.Quarter.SPRING.
}

There is a empty interface Weather, and i have create two enum Quarter and Temperature in the interface.

If i want to use the SPRING, i can use it by .

I have created two enum for Temperature and Quarter in the interface Weather, which is now empty.
I can use the SPRING by Weather.Quarter.SPRING.

In China, there is an adage that says:

Knowledges obtained on the papers always feel shallow, must know this thing to practice.

That’s all the information I have; hopefully you get it.

--

--

onxy
onxy

Written by onxy

0 Followers

10-year Java web dev with expertise in Java, Spring Boot, and Spring Cloud. Adept at communicating ideas. Adaptable, reliable, and serious.

No responses yet