For working professionals
For fresh graduates
More
6. JDK in Java
7. C++ Vs Java
16. Java If-else
18. Loops in Java
20. For Loop in Java
46. Packages in Java
53. Java Collection
56. Generics In Java
57. Java Interfaces
60. Streams in Java
63. Thread in Java
67. Deadlock in Java
74. Applet in Java
75. Java Swing
76. Java Frameworks
78. JUnit Testing
81. Jar file in Java
82. Java Clean Code
86. Java 8 features
87. String in Java
93. HashMap in Java
98. Enum in Java
101. Hashcode in Java
105. Linked List in Java
109. Array Length in Java
111. Split in java
112. Map In Java
115. HashSet in Java
118. DateFormat in Java
121. Java List Size
122. Java APIs
128. Identifiers in Java
130. Set in Java
132. Try Catch in Java
133. Bubble Sort in Java
135. Queue in Java
142. Jagged Array in Java
144. Java String Format
145. Replace in Java
146. charAt() in Java
147. CompareTo in Java
151. parseInt in Java
153. Abstraction in Java
154. String Input in Java
156. instanceof in Java
157. Math Floor in Java
158. Selection Sort Java
159. int to char in Java
164. Deque in Java
172. Trim in Java
173. RxJava
174. Recursion in Java
175. HashSet Java
177. Square Root in Java
190. Javafx
Enums in Java are a special data type that lets you define a fixed set of constants. They help make your code more readable, maintainable, and type-safe. Instead of static final variables, enums offer a cleaner and more organized way to group related constants.
Introduced in Java 5, enums are much more powerful than they appear. They are full-fledged classes that can include fields, methods, and constructors. This allows developers to add behavior to enum values and use them meaningfully. Enums are commonly used to represent fixed sets such as days of the week, directions, or status codes.
By using enums, you avoid hard-coded values like magic numbers or strings, making your code easier to manage and less error-prone. This blog will explore basic and advanced enums, including enum methods, constructors, and best practices. Many software engineering courses emphasize enums as an essential topic for writing better Java code.
Basics of Enum in Java
An enum data type in Java is a special class type representing a group of constants (unchangeable variables). Enums are implicitly final and static, which means they can't be extended (inherited) and their constants are accessible directly through the enum type name.
The key features of enum in Java include:
Also read: Data Types in Java: Primitive & Non-Primitive Data Types
You should consider using an enum in Java in the following scenarios:
The syntax for a basic enum declaration in Java is straightforward:
// Basic enum declaration in Java
public enum Season {
WINTER,
SPRING,
SUMMER,
FALL
}
In this example, WINTER, SPRING, SUMMER, and FALL are enum constants. Each constant is an instance of the Season enum type. By convention, enum constants are written in uppercase letters to distinguish them from variables.
Enhance your abilities through these best-in-class certifications.
To create and use an enum in Java, follow these steps:
Let's look at a simple example:
// How to create enum in Java
public class EnumExample {
// Creating the enum
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public static void main(String[] args) {
// Using the enum
Day today = Day.WEDNESDAY;
System.out.println("Today is: " + today);
// Comparing enum values (using == is safe with enums)
if (today == Day.WEDNESDAY) {
System.out.println("It's middle of the week!");
}
}
}
Output:
Today is: WEDNESDAY
It's middle of the week!
Must read: Collection Framework in Java
One of the powerful features of enum in Java is that you can associate data with each enum constant. This allows you to add more information to your constants beyond just their names.
Here's how to create an enum with values in Java:
// Enum with values in Java
public enum Planet {
MERCURY(3.303e+23, 2.4397e6),
VENUS(4.869e+24, 6.0518e6),
EARTH(5.976e+24, 6.37814e6),
MARS(6.421e+23, 3.3972e6),
JUPITER(1.9e+27, 7.1492e7),
SATURN(5.688e+26, 6.0268e7),
URANUS(8.686e+25, 2.5559e7),
NEPTUNE(1.024e+26, 2.4746e7);
private final double mass; // in kilograms
private final double radius; // in meters
// Enum constructor
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
// Getters
public double getMass() {
return mass;
}
public double getRadius() {
return radius;
}
// Custom method
public double surfaceGravity() {
double G = 6.67300E-11; // universal gravitational constant
return G * mass / (radius * radius);
}
public double surfaceWeight(double otherMass) {
return otherMass * surfaceGravity();
}
}
In this example, each planet has associated mass and radius values. We use an enum constructor in Java to initialize these fields for each constant.
An enum constructor in Java is a special type of constructor that's called when enum constants are created. Here are the key points about enum with constructor in Java:
Let's see another example of an enum constructor in Java:
// Enum with constructor in Java
public enum CoffeeSize {
// Enum constants with constructor arguments
SMALL(8),
MEDIUM(12),
LARGE(16),
EXTRA_LARGE(20);
private final int ounces;
// Private constructor
private CoffeeSize(int ounces) {
this.ounces = ounces;
}
public int getOunces() {
return ounces;
}
}
public class CoffeeShop {
public static void main(String[] args) {
CoffeeSize size = CoffeeSize.MEDIUM;
System.out.println("Coffee size: " + size + " (" + size.getOunces() + " oz)");
// Using values() method to iterate through all enum constants
System.out.println("\nAvailable sizes:");
for (CoffeeSize cs : CoffeeSize.values()) {
System.out.println(cs + " - " + cs.getOunces() + " oz");
}
}
}
Output:
Coffee size: MEDIUM (12 oz)
Available sizes:
SMALL - 8 oz
MEDIUM - 12 oz
LARGE - 16 oz
EXTRA_LARGE - 20 oz
Also check: Design Patterns in Java
Every enum in Java automatically inherits from java.lang.Enum class, which provides several useful methods:
Method | Description |
values() | Returns an array containing all enum constants |
valueOf(String name) | Returns the enum constant with the specified name |
name() | Returns the exact name of this enum constant |
ordinal() | Returns the position of the enum constant (0-based) |
compareTo(E o) | Compares enum constants based on their ordinal values |
equals(Object other) | Compares enum references for equality |
Here's an example demonstrating these built-in methods:
// Exploring built-in enum methods in Java
public class EnumMethodsDemo {
public enum TrafficLight {
RED, YELLOW, GREEN
}
public static void main(String[] args) {
// Using values() method
System.out.println("All traffic light states:");
for (TrafficLight light : TrafficLight.values()) {
System.out.println(light);
}
// Using valueOf() method
TrafficLight light1 = TrafficLight.valueOf("RED");
System.out.println("\nlight1: " + light1);
// Using name() method
System.out.println("light1 name: " + light1.name());
// Using ordinal() method
System.out.println("light1 ordinal: " + light1.ordinal());
// Using compareTo() method
TrafficLight light2 = TrafficLight.GREEN;
System.out.println("light1.compareTo(light2): " + light1.compareTo(light2));
// Using == for comparison (safe with enums)
System.out.println("light1 == TrafficLight.RED: " + (light1 == TrafficLight.RED));
}
}
Output:
All traffic light states:
RED
YELLOW
GREEN
light1: RED
light1 name: RED
light1 ordinal: 0
light1.compareTo(light2): -2
light1 == TrafficLight.RED: true
Must explore: Comparable and Comparator in Java
You can add custom methods to an enum in Java, just like in a regular class. This allows you to encapsulate behavior specific to each enum constant.
// Enum with custom methods in Java
public enum Operation {
ADD("+") {
@Override
public double apply(double x, double y) {
return x + y;
}
},
SUBTRACT("-") {
@Override
public double apply(double x, double y) {
return x - y;
}
},
MULTIPLY("*") {
@Override
public double apply(double x, double y) {
return x * y;
}
},
DIVIDE("/") {
@Override
public double apply(double x, double y) {
if (y == 0) {
throw new ArithmeticException("Division by zero");
}
return x / y;
}
};
private final String symbol;
Operation(String symbol) {
this.symbol = symbol;
}
public String getSymbol() {
return symbol;
}
// Abstract method to be implemented by each enum constant
public abstract double apply(double x, double y);
}
public class CalculatorDemo {
public static void main(String[] args) {
double x = 10;
double y = 5;
for (Operation op : Operation.values()) {
System.out.printf("%f %s %f = %f%n", x, op.getSymbol(), y, op.apply(x, y));
}
}
}
Output:
10.000000 + 5.000000 = 15.000000
10.000000 - 5.000000 = 5.000000
10.000000 * 5.000000 = 50.000000
10.000000 / 5.000000 = 2.000000
An enum in Java can implement interfaces, which provides a way to ensure that all enum constants provide implementations for the interface methods.
// Enum implementing an interface in Java
interface Describable {
String getDescription();
}
public enum PaymentMethod implements Describable {
CREDIT_CARD("Payment using credit card"),
DEBIT_CARD("Payment using debit card"),
PAYPAL("Payment using PayPal"),
CRYPTO("Payment using cryptocurrency"),
BANK_TRANSFER("Payment using bank transfer");
private final String description;
PaymentMethod(String description) {
this.description = description;
}
// Implementing the interface method
@Override
public String getDescription() {
return description;
}
}
public class PaymentDemo {
public static void main(String[] args) {
System.out.println("Available payment methods:");
for (PaymentMethod method : PaymentMethod.values()) {
System.out.println("- " + method + ": " + method.getDescription());
}
}
}
Output:
Available payment methods:
- CREDIT_CARD: Payment using credit card
- DEBIT_CARD: Payment using debit card
- PAYPAL: Payment using PayPal
- CRYPTO: Payment using cryptocurrency
- BANK_TRANSFER: Payment using bank transfer
Using enum in Java with switch statements is one of the most common and effective applications. It provides type safety and readability that traditional constants cannot match.
// Using enum in switch statements
public enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class WeekdaySchedule {
public static void main(String[] args) {
Day today = Day.MONDAY;
switch (today) {
case MONDAY:
System.out.println("Start of work week. Team meeting at 9 AM.");
break;
case TUESDAY:
case WEDNESDAY:
case THURSDAY:
System.out.println("Regular work day.");
break;
case FRIDAY:
System.out.println("Casual Friday. Weekly report due.");
break;
case SATURDAY:
case SUNDAY:
System.out.println("Weekend!");
break;
default:
// This case will never execute since all enum values are covered
System.out.println("Invalid day");
}
}
}
Output:
Start of work week. Team meeting at 9 AM.
Check out: Switch Case in Java
One of the lesser-known applications of enum in Java is implementing the Singleton pattern. This approach is recommended by Joshua Bloch in "Effective Java" as it provides serialization safety and thread safety for free.
// Singleton pattern using enum in Java
public enum DatabaseConnection {
INSTANCE;
private Connection connection;
// Private constructor
private DatabaseConnection() {
// Initialization code
System.out.println("Creating database connection...");
// In a real application, this would connect to an actual database
connection = null; // Placeholder for actual connection
}
public Connection getConnection() {
if (connection == null) {
// Initialize connection if not already done
// This is just a simplified example
System.out.println("Connection initialized");
}
return connection;
}
public void executeQuery(String query) {
System.out.println("Executing query: " + query);
// Implementation details
}
}
public class SingletonDemo {
public static void main(String[] args) {
// Access the singleton instance
DatabaseConnection db = DatabaseConnection.INSTANCE;
db.executeQuery("SELECT * FROM users");
// Another reference to the same instance
DatabaseConnection anotherDb = DatabaseConnection.INSTANCE;
System.out.println("Same instance? " + (db == anotherDb));
}
}
Output:
Creating database connection...
Executing query: SELECT * FROM users
Same instance? true
Also read: Java Classes and Objects
Enums are perfect for implementing simple state machines in Java:
// State machine using enum in Java
public enum OrderStatus {
NEW {
@Override
public OrderStatus nextState() {
return PROCESSING;
}
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == PROCESSING || nextStatus == CANCELED;
}
},
PROCESSING {
@Override
public OrderStatus nextState() {
return SHIPPED;
}
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == SHIPPED || nextStatus == CANCELED;
}
},
SHIPPED {
@Override
public OrderStatus nextState() {
return DELIVERED;
}
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == DELIVERED || nextStatus == RETURNED;
}
},
DELIVERED {
@Override
public OrderStatus nextState() {
return this; // Terminal state
}
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return nextStatus == RETURNED;
}
},
RETURNED {
@Override
public OrderStatus nextState() {
return this; // Terminal state
}
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return false; // Cannot transition from this state
}
},
CANCELED {
@Override
public OrderStatus nextState() {
return this; // Terminal state
}
@Override
public boolean canTransitionTo(OrderStatus nextStatus) {
return false; // Cannot transition from this state
}
};
// Abstract methods to be implemented by each state
public abstract OrderStatus nextState();
public abstract boolean canTransitionTo(OrderStatus nextStatus);
}
public class OrderProcessingDemo {
public static void main(String[] args) {
OrderStatus status = OrderStatus.NEW;
System.out.println("Initial status: " + status);
// Simulate order processing flow
while (status != status.nextState()) {
status = status.nextState();
System.out.println("Status updated to: " + status);
}
}
}
Output:
Initial status: NEW
Status updated to: PROCESSING
Status updated to: SHIPPED
Status updated to: DELIVERED
Enum in Java is more than just a way to define constants. It offers a type-safe and expressive approach to represent fixed sets of values. With support for fields, constructors, methods, and even interface implementation, enums make your code more readable and less error-prone.
Java also provides built-in features like EnumSet and EnumMap for efficient enum handling. Whether you're learning the basics or applying advanced enum techniques, mastering this feature enhances your ability to write clean and maintainable Java code across various use cases.
Enums in Java are a special type of class with some restrictions:
No, Java enums cannot extend other classes because they implicitly extend java.lang.Enum. However, enums can implement interfaces, which allows you to define common behavior across different enum types.
Yes, you can add methods to individual enum constants in Java using anonymous class bodies. This allows each constant to have its own implementation of methods, as shown in the Operation and OrderStatus examples earlier in this article.
Yes, Java enums are inherently thread-safe for basic operations because enum constants are created when the enum class is loaded, and they are effectively immutable. However, if you add mutable fields to your enum, you'll need to handle thread safety manually.
To convert a String to an enum in Java, you can use the static valueOf() method that's automatically generated for every enum type:
Day day = Day.valueOf("MONDAY"); // Converts the string "MONDAY" to Day.MONDAY
Note that the string must exactly match the name of an enum constant (case-sensitive), or a IllegalArgumentException will be thrown.
You can iterate through all enum values using the static values() method:
for (Day day : Day.values()) {
System.out.println(day);
}
Yes, enums can have constructors with parameters in Java. These parameters are specified when declaring the enum constants:
public enum Currency {
USD("US Dollar", "$"),
EUR("Euro", "€"),
GBP("British Pound", "£"),
JPY("Japanese Yen", "¥");
private final String fullName;
private final String symbol;
Currency(String fullName, String symbol) {
this.fullName = fullName;
this.symbol = symbol;
}
public String getFullName() {
return fullName;
}
public String getSymbol() {
return symbol;
}
}
You can override methods for individual enum constants using anonymous class bodies, and you can override methods inherited from Object (like toString()). However, you cannot override the final methods inherited from Enum like name(), ordinal(), or valueOf().
To use enums with JPA and Hibernate, you can use the @Enumerated annotation to specify how the enum should be stored in the database:
public class Employee {
@Id
private Long id;
private String name;
@Enumerated(EnumType.STRING) // Store enum as string (enum name)
private EmployeeStatus status;
// Alternative: store as ordinal (numeric position)
// @Enumerated(EnumType.ORDINAL)
// private EmployeeStatus status;
// Getters and setters
}
public enum EmployeeStatus {
ACTIVE, ON_LEAVE, TERMINATED
}
Most JSON libraries like Jackson and Gson handle Java enums naturally. By default, Jackson serializes enums as their name (string representation):
public class User {
private String username;
private Role role;
// Getters and setters
}
public enum Role {
ADMIN, USER, GUEST
}
// Using Jackson
ObjectMapper mapper = new ObjectMapper();
User user = new User();
user.setUsername("john");
user.setRole(Role.ADMIN);
String json = mapper.writeValueAsString(user);
// Output: {"username":"john","role":"ADMIN"}
Enums in Java are generally lightweight, but each enum constant is a singleton object, so they do consume some memory. For simple enums without fields or methods, the memory overhead is minimal. However, for complex enums with many fields and methods, the memory footprint can increase. In most cases, the benefits of using enums outweigh any memory concerns.
Take the Free Quiz on Java
Answer quick questions and assess your Java knowledge
Author|900 articles published
Previous
Next
Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)
Indian Nationals
1800 210 2020
Foreign Nationals
+918068792934
1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.
2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.