Enum with Constructor and Methods in Java

Enums in Java are more powerful than in many other languages. They can have constructors, methods, fields, and even implement interfaces.

Basic Enum Syntax

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

Enum with Constructor, Fields and Methods

Simple Example

public enum Planet {
// Enum constants with constructor arguments
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);
// Fields
private final double mass;   // in kilograms
private final double radius; // in meters
// Constructor (always private by default)
Planet(double mass, double radius) {
this.mass = mass;
this.radius = radius;
}
// Methods
public double getMass() {
return mass;
}
public double getRadius() {
return radius;
}
public double getSurfaceGravity() {
final double G = 6.67300E-11; // gravitational constant
return G * mass / (radius * radius);
}
public double getSurfaceWeight(double otherMass) {
return otherMass * getSurfaceGravity();
}
}

Usage Example

public class PlanetTest {
public static void main(String[] args) {
double earthWeight = 175; // in pounds
double mass = earthWeight / Planet.EARTH.getSurfaceGravity();
for (Planet p : Planet.values()) {
System.out.printf("Your weight on %s is %f%n",
p, p.getSurfaceWeight(mass));
}
}
}

Advanced Enum Features

Enum with Multiple Fields and Custom Methods

public enum Operation {
PLUS("+") {
public double apply(double x, double y) { return x + y; }
},
MINUS("-") {
public double apply(double x, double y) { return x - y; }
},
TIMES("*") {
public double apply(double x, double y) { return x * y; }
},
DIVIDE("/") {
public double apply(double x, double y) { return x / y; }
};
private final String symbol;
// Constructor
Operation(String symbol) {
this.symbol = symbol;
}
// Abstract method - each constant must implement
public abstract double apply(double x, double y);
// Regular method
public String getSymbol() {
return symbol;
}
// Static utility method
public static Operation fromSymbol(String symbol) {
for (Operation op : values()) {
if (op.symbol.equals(symbol)) {
return op;
}
}
throw new IllegalArgumentException("Unknown operator: " + symbol);
}
}

Usage

public class Calculator {
public static void main(String[] args) {
double x = 10, y = 5;
for (Operation op : Operation.values()) {
System.out.printf("%f %s %f = %f%n", 
x, op.getSymbol(), y, op.apply(x, y));
}
// Using the static method
Operation plus = Operation.fromSymbol("+");
System.out.println("5 + 3 = " + plus.apply(5, 3));
}
}

Enum with State and Behavior

Complex Example with Multiple Constructors

public enum HttpStatus {
// Success responses
OK(200, "OK"),
CREATED(201, "Created"),
ACCEPTED(202, "Accepted"),
// Client error responses
BAD_REQUEST(400, "Bad Request"),
UNAUTHORIZED(401, "Unauthorized"),
FORBIDDEN(403, "Forbidden"),
NOT_FOUND(404, "Not Found"),
// Server error responses  
INTERNAL_SERVER_ERROR(500, "Internal Server Error"),
NOT_IMPLEMENTED(501, "Not Implemented"),
BAD_GATEWAY(502, "Bad Gateway");
private final int code;
private final String description;
private final Category category;
// Regular constructor
HttpStatus(int code, String description) {
this.code = code;
this.description = description;
this.category = determineCategory(code);
}
// Private helper method
private Category determineCategory(int code) {
if (code >= 200 && code < 300) return Category.SUCCESS;
if (code >= 400 && code < 500) return Category.CLIENT_ERROR;
if (code >= 500 && code < 600) return Category.SERVER_ERROR;
return Category.UNKNOWN;
}
// Methods
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
public Category getCategory() {
return category;
}
public boolean isSuccess() {
return category == Category.SUCCESS;
}
public boolean isError() {
return category == Category.CLIENT_ERROR || category == Category.SERVER_ERROR;
}
// Static lookup method
public static HttpStatus fromCode(int code) {
for (HttpStatus status : values()) {
if (status.code == code) {
return status;
}
}
throw new IllegalArgumentException("Unknown HTTP status code: " + code);
}
// Nested enum
public enum Category {
SUCCESS, CLIENT_ERROR, SERVER_ERROR, UNKNOWN
}
@Override
public String toString() {
return code + " " + description;
}
}

Usage

public class HttpStatusTest {
public static void main(String[] args) {
HttpStatus status = HttpStatus.NOT_FOUND;
System.out.println("Code: " + status.getCode());
System.out.println("Description: " + status.getDescription());
System.out.println("Category: " + status.getCategory());
System.out.println("Is error: " + status.isError());
System.out.println("Is success: " + status.isSuccess());
System.out.println("ToString: " + status);
// Lookup by code
HttpStatus found = HttpStatus.fromCode(200);
System.out.println("Found: " + found);
}
}

Enum Implementing Interface

// Interface
public interface Cacheable {
String getCacheKey();
boolean isCacheable();
}
// Enum implementing interface
public enum UserRole implements Cacheable {
ADMIN("admin", 1, true),
MODERATOR("moderator", 2, true),
USER("user", 3, true),
GUEST("guest", 4, false);
private final String roleName;
private final int level;
private final boolean cacheable;
UserRole(String roleName, int level, boolean cacheable) {
this.roleName = roleName;
this.level = level;
this.cacheable = cacheable;
}
// Interface method implementations
@Override
public String getCacheKey() {
return "ROLE_" + name();
}
@Override
public boolean isCacheable() {
return cacheable;
}
// Additional methods
public String getRoleName() {
return roleName;
}
public int getLevel() {
return level;
}
public boolean hasPermission(String permission) {
// Logic to check permissions based on role level
return this.level <= getRequiredLevel(permission);
}
private int getRequiredLevel(String permission) {
// Permission level mapping logic
return switch (permission) {
case "DELETE" -> 1;
case "EDIT" -> 2;
case "VIEW" -> 3;
default -> 4;
};
}
}

Enum with Singleton Pattern

public enum DatabaseConnection {
INSTANCE;
private Connection connection;
DatabaseConnection() {
// Initialize connection
initializeConnection();
}
private void initializeConnection() {
try {
// Simulate connection creation
System.out.println("Creating database connection...");
// this.connection = DriverManager.getConnection(url);
} catch (Exception e) {
throw new RuntimeException("Failed to create database connection", e);
}
}
public Connection getConnection() {
return connection;
}
public void executeQuery(String query) {
System.out.println("Executing: " + query);
// Actual query execution logic
}
public void close() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException e) {
System.err.println("Error closing connection: " + e.getMessage());
}
}
}

Singleton Usage

public class SingletonDemo {
public static void main(String[] args) {
// Get the singleton instance
DatabaseConnection db = DatabaseConnection.INSTANCE;
db.executeQuery("SELECT * FROM users");
// All calls to INSTANCE return the same instance
DatabaseConnection sameInstance = DatabaseConnection.INSTANCE;
System.out.println("Same instance? " + (db == sameInstance)); // true
}
}

Best Practices

  1. Use descriptive names for enum constants
  2. Keep enum constructors private (they already are by default)
  3. Make enum fields final when possible for immutability
  4. Override toString() for better readability
  5. Use enum for fixed set of constants that won't change frequently
  6. Consider using enums instead of boolean parameters for better readability
// BAD - boolean parameters are confusing
public void setVisible(boolean visible, boolean modal)
// GOOD - enum parameters are clear
public void setVisible(Visibility visible, Modality modal)
public enum Visibility { VISIBLE, HIDDEN }
public enum Modality { MODAL, MODELESS }

Key Benefits

  • Type safety - Compiler prevents invalid values
  • Rich functionality - Can have methods, fields, and implement interfaces
  • Singleton support - Natural implementation of singleton pattern
  • Serialization safety - Built-in serialization support
  • Switch statement compatibility - Can be used in switch statements

Enums with constructors and methods provide a powerful way to represent fixed sets of related constants with associated behavior and data.

Leave a Reply

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


Macro Nepal Helper