google-site-verification: google61fe8ba583a51912.html
Enum Types Declaration in Java

Introduction

Imagine you're building a traffic light system. The light can only be in one of three states: RED, YELLOW, or GREEN. You could use strings like "red", "yellow", "green", but what if someone misspells "gren" or uses "blue"? Enum types in Java solve this problem perfectly—they allow you to define a fixed set of constants that are type-safe and self-documenting.

Enums (short for enumerations) are special Java types that represent a fixed set of constants. They're like classes but with a predefined set of instances. Think of them as pre-made objects that you can choose from!


What are Enum Types?

Enum types are special data types that enable a variable to be a set of predefined constants. The variable must equal one of the values that have been predefined for it.

Key Characteristics:

  • Type-safe - Compiler checks for valid values
  • Fixed set of instances - Predefined constants
  • Can have fields, methods, and constructors - Like classes
  • Implicitly final - Cannot be extended
  • Implicitly extends java.lang.Enum - Automatic inheritance

Code Explanation with Examples

Example 1: Basic Enum Declaration

// ✅ BASIC ENUM DECLARATION // Simple enum with just constant names enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } // Enum with simple behavior enum TrafficLight { RED, YELLOW, GREEN } // Enum with different access levels enum CoffeeSize { SMALL, MEDIUM, LARGE, EXTRA_LARGE } public class BasicEnumDemo { public static void main(String[] args) { System.out.println("=== BASIC ENUM DECLARATION DEMO ==="); // Using enum values Day today = Day.MONDAY; TrafficLight currentLight = TrafficLight.RED; CoffeeSize myCoffee = CoffeeSize.LARGE; System.out.println("Today is: " + today); System.out.println("Traffic light is: " + currentLight); System.out.println("Coffee size: " + myCoffee); // Enum in switch statements (perfect match!) System.out.println("\n=== SWITCH STATEMENT WITH ENUM ==="); switch (today) { case MONDAY: System.out.println("Start of work week!"); break; case FRIDAY: System.out.println("Weekend is coming!"); break; case SATURDAY: case SUNDAY: System.out.println("Weekend!"); break; default: System.out.println("Regular work day"); } // Getting all enum values System.out.println("\n=== ALL ENUM VALUES ==="); Day[] allDays = Day.values(); for (Day day : allDays) { System.out.println("Day: " + day); } // Enum methods (inherited from java.lang.Enum) System.out.println("\n=== ENUM METHODS ==="); System.out.println("Name: " + today.name()); System.out.println("Ordinal: " + today.ordinal()); // Position (0-based) System.out.println("ToString: " + today.toString()); // Converting string to enum String dayString = "FRIDAY"; Day parsedDay = Day.valueOf(dayString); System.out.println("Parsed from string: " + parsedDay); // Comparing enums System.out.println("\n=== ENUM COMPARISON ==="); System.out.println("today == Day.MONDAY: " + (today == Day.MONDAY)); System.out.println("today.equals(Day.MONDAY): " + today.equals(Day.MONDAY)); // Enum in collections System.out.println("\n=== ENUMS IN COLLECTIONS ==="); java.util.Set<Day> weekend = java.util.EnumSet.of(Day.SATURDAY, Day.SUNDAY); System.out.println("Weekend days: " + weekend); java.util.Map<Day, String> activities = new java.util.EnumMap<>(Day.class); activities.put(Day.MONDAY, "Work"); activities.put(Day.SATURDAY, "Relax"); System.out.println("Activities: " + activities); } }

Output:

=== BASIC ENUM DECLARATION DEMO === Today is: MONDAY Traffic light is: RED Coffee size: LARGE === SWITCH STATEMENT WITH ENUM === Start of work week! === ALL ENUM VALUES === Day: SUNDAY Day: MONDAY Day: TUESDAY Day: WEDNESDAY Day: THURSDAY Day: FRIDAY Day: SATURDAY === ENUM METHODS === Name: MONDAY Ordinal: 1 ToString: MONDAY Parsed from string: FRIDAY === ENUM COMPARISON === today == Day.MONDAY: true today.equals(Day.MONDAY): true === ENUMS IN COLLECTIONS === Weekend days: [SATURDAY, SUNDAY] Activities: {MONDAY=Work, SATURDAY=Relax}

Example 2: Enum with Fields, Methods, and Constructors

// ✅ ENUM WITH FIELDS, METHODS, AND CONSTRUCTORS // Each enum constant can have its own data and behavior 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 (instance variables) private final double mass; // in kilograms private final double radius; // in meters // Constructor (automatically private) Planet(double mass, double radius) { this.mass = mass; this.radius = radius; } // Public getters public double getMass() { return mass; } public double getRadius() { return radius; } // Universal gravitational constant (m^3 kg^-1 s^-2) public static final double G = 6.67300E-11; // Method to calculate surface gravity public double surfaceGravity() { return G * mass / (radius * radius); } // Method to calculate weight on this planet public double surfaceWeight(double otherMass) { return otherMass * surfaceGravity(); } // Override toString for better representation @Override public String toString() { return name() + " {mass=" + String.format("%.2e", mass) + " kg, radius=" + String.format("%.2e", radius) + " m}"; } } // Enum with different types of fields enum HttpStatus { // Constants with status code and message OK(200, "OK"), CREATED(201, "Created"), BAD_REQUEST(400, "Bad Request"), UNAUTHORIZED(401, "Unauthorized"), FORBIDDEN(403, "Forbidden"), NOT_FOUND(404, "Not Found"), INTERNAL_SERVER_ERROR(500, "Internal Server Error"); private final int code; private final String message; HttpStatus(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public String getMessage() { return message; } // Static method to find enum by code public static HttpStatus fromCode(int code) { for (HttpStatus status : values()) { if (status.code == code) { return status; } } throw new IllegalArgumentException("No HTTP status with code: " + code); } // Check if status is successful (2xx) public boolean isSuccess() { return code >= 200 && code < 300; } // Check if status is client error (4xx) public boolean isClientError() { return code >= 400 && code < 500; } // Check if status is server error (5xx) public boolean isServerError() { return code >= 500 && code < 600; } @Override public String toString() { return code + " " + message; } } public class AdvancedEnumDemo { public static void main(String[] args) { System.out.println("=== ADVANCED ENUM WITH FIELDS AND METHODS ==="); // Planet enum demonstration System.out.println("\n=== PLANET ENUM DEMO ==="); double earthWeight = 75; // kg double mass = earthWeight / Planet.EARTH.surfaceGravity(); System.out.println("Your weight on different planets:"); for (Planet p : Planet.values()) { System.out.printf(" %-8s: %6.2f kg%n", p, p.surfaceWeight(mass)); } System.out.println("\n=== PLANET DETAILS ==="); for (Planet p : Planet.values()) { System.out.println(p); System.out.printf(" Surface gravity: %.2f m/s²%n", p.surfaceGravity()); } // HTTP Status enum demonstration System.out.println("\n=== HTTP STATUS ENUM DEMO ==="); HttpStatus status = HttpStatus.OK; System.out.println("Current status: " + status); System.out.println("Code: " + status.getCode()); System.out.println("Message: " + status.getMessage()); System.out.println("Is success: " + status.isSuccess()); System.out.println("\n=== ALL HTTP STATUS CODES ==="); for (HttpStatus httpStatus : HttpStatus.values()) { System.out.printf("%-25s: %-3d - %s%n", httpStatus.name(), httpStatus.getCode(), httpStatus.getMessage()); } System.out.println("\n=== FINDING STATUS BY CODE ==="); HttpStatus foundStatus = HttpStatus.fromCode(404); System.out.println("Status for code 404: " + foundStatus); System.out.println("Is client error: " + foundStatus.isClientError()); System.out.println("\n=== STATUS CATEGORIES ==="); System.out.println("Successful statuses:"); for (HttpStatus httpStatus : HttpStatus.values()) { if (httpStatus.isSuccess()) { System.out.println(" " + httpStatus); } } System.out.println("Client error statuses:"); for (HttpStatus httpStatus : HttpStatus.values()) { if (httpStatus.isClientError()) { System.out.println(" " + httpStatus); } } // Using enums in practical scenarios System.out.println("\n=== PRACTICAL USAGE ==="); processHttpResponse(200); processHttpResponse(404); processHttpResponse(500); } public static void processHttpResponse(int statusCode) { HttpStatus status = HttpStatus.fromCode(statusCode); System.out.println("\nProcessing HTTP response: " + status); if (status.isSuccess()) { System.out.println("✅ Success! Processing response data..."); } else if (status.isClientError()) { System.out.println("❌ Client error! Check your request..."); } else if (status.isServerError()) { System.out.println("⚠️ Server error! Try again later..."); } switch (status) { case OK: System.out.println(" Everything worked as expected"); break; case NOT_FOUND: System.out.println(" The requested resource was not found"); break; case INTERNAL_SERVER_ERROR: System.out.println(" Something went wrong on the server"); break; default: System.out.println(" Handling status: " + status.getMessage()); } } }

Output:

=== ADVANCED ENUM WITH FIELDS AND METHODS === === PLANET ENUM DEMO === Your weight on different planets: MERCURY : 28.30 kg VENUS : 67.69 kg EARTH : 75.00 kg MARS : 28.33 kg JUPITER : 189.74 kg SATURN : 79.63 kg URANUS : 67.95 kg NEPTUNE : 85.23 kg === PLANET DETAILS === MERCURY {mass=3.30e+23 kg, radius=2.44e+06 m} Surface gravity: 3.70 m/s² VENUS {mass=4.87e+24 kg, radius=6.05e+06 m} Surface gravity: 8.87 m/s² EARTH {mass=5.98e+24 kg, radius=6.38e+06 m} Surface gravity: 9.80 m/s² MARS {mass=6.42e+23 kg, radius=3.40e+06 m} Surface gravity: 3.71 m/s² JUPITER {mass=1.90e+27 kg, radius=7.15e+07 m} Surface gravity: 24.79 m/s² SATURN {mass=5.69e+26 kg, radius=6.03e+07 m} Surface gravity: 10.44 m/s² URANUS {mass=8.69e+25 kg, radius=2.56e+07 m} Surface gravity: 8.87 m/s² NEPTUNE {mass=1.02e+26 kg, radius=2.47e+07 m} Surface gravity: 11.15 m/s² === HTTP STATUS ENUM DEMO === Current status: 200 OK Code: 200 Message: OK Is success: true === ALL HTTP STATUS CODES === OK : 200 - OK CREATED : 201 - Created BAD_REQUEST : 400 - Bad Request UNAUTHORIZED : 401 - Unauthorized FORBIDDEN : 403 - Forbidden NOT_FOUND : 404 - Not Found INTERNAL_SERVER_ERROR : 500 - Internal Server Error === FINDING STATUS BY CODE === Status for code 404: 404 Not Found Is client error: true === STATUS CATEGORIES === Successful statuses: 200 OK 201 Created Client error statuses: 400 Bad Request 401 Unauthorized 403 Forbidden 404 Not Found === PRACTICAL USAGE === Processing HTTP response: 200 OK ✅ Success! Processing response data... Everything worked as expected Processing HTTP response: 404 Not Found ❌ Client error! Check your request... The requested resource was not found Processing HTTP response: 500 Internal Server Error ⚠️ Server error! Try again later... Something went wrong on the server

Example 3: Enum with Constant-Specific Methods

// ✅ ENUM WITH CONSTANT-SPECIFIC METHOD IMPLEMENTATIONS // Each enum constant can override methods with its own behavior enum Operation { // Constants with lambda expressions for behavior 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) { if (y == 0) { throw new ArithmeticException("Division by zero!"); } return x / y; } }, POWER("^") { public double apply(double x, double y) { return Math.pow(x, y); } }, MODULUS("%") { public double apply(double x, double y) { return x % y; } }; private final String symbol; Operation(String symbol) { this.symbol = symbol; } // Abstract method - each constant must implement public abstract double apply(double x, double y); public String getSymbol() { return symbol; } @Override public String toString() { return symbol; } } // Enum with different behaviors for each constant enum FileType { TEXT(".txt") { @Override public void process(String content) { System.out.println("Processing text file: " + content); } @Override public boolean isValid(String filename) { return filename.toLowerCase().endsWith(".txt"); } }, JSON(".json") { @Override public void process(String content) { System.out.println("Parsing JSON: " + content); // Simulate JSON parsing if (content.trim().startsWith("{")) { System.out.println(" ✓ Valid JSON structure"); } else { System.out.println(" ✗ Invalid JSON structure"); } } @Override public boolean isValid(String filename) { return filename.toLowerCase().endsWith(".json"); } }, XML(".xml") { @Override public void process(String content) { System.out.println("Parsing XML: " + content); // Simulate XML parsing if (content.trim().startsWith("<")) { System.out.println(" ✓ Valid XML structure"); } else { System.out.println(" ✗ Invalid XML structure"); } } @Override public boolean isValid(String filename) { return filename.toLowerCase().endsWith(".xml"); } }, CSV(".csv") { @Override public void process(String content) { System.out.println("Processing CSV: " + content); String[] rows = content.split("\n"); System.out.println(" Found " + rows.length + " rows"); for (int i = 0; i < Math.min(rows.length, 3); i++) { System.out.println(" Row " + (i + 1) + ": " + rows[i]); } } @Override public boolean isValid(String filename) { return filename.toLowerCase().endsWith(".csv"); } }; private final String extension; FileType(String extension) { this.extension = extension; } // Abstract methods that each constant must implement public abstract void process(String content); public abstract boolean isValid(String filename); public String getExtension() { return extension; } // Static method to detect file type from filename public static FileType fromFilename(String filename) { for (FileType type : values()) { if (type.isValid(filename)) { return type; } } throw new IllegalArgumentException("Unknown file type: " + filename); } } // Enum with strategy pattern enum NotificationChannel { EMAIL { @Override public void sendNotification(String message, String recipient) { System.out.println("📧 Sending email to: " + recipient); System.out.println(" Subject: Notification"); System.out.println(" Body: " + message); System.out.println(" → Email sent successfully!"); } @Override public boolean validateRecipient(String recipient) { return recipient.contains("@") && recipient.contains("."); } }, SMS { @Override public void sendNotification(String message, String recipient) { System.out.println("📱 Sending SMS to: " + recipient); System.out.println(" Message: " + (message.length() > 20 ? message.substring(0, 20) + "..." : message)); System.out.println(" → SMS sent successfully!"); } @Override public boolean validateRecipient(String recipient) { // Simple phone number validation return recipient.matches("\\+?[0-9]{10,15}"); } }, PUSH { @Override public void sendNotification(String message, String recipient) { System.out.println("📲 Sending push notification to device: " + recipient); System.out.println(" Title: App Notification"); System.out.println(" Body: " + message); System.out.println(" → Push notification sent!"); } @Override public boolean validateRecipient(String recipient) { // Device token validation (simplified) return recipient.length() == 64 && recipient.matches("[0-9a-fA-F]+"); } }; // Abstract methods public abstract void sendNotification(String message, String recipient); public abstract boolean validateRecipient(String recipient); // Template method with common behavior public final void sendSecureNotification(String message, String recipient) { System.out.println("\n=== Sending Secure Notification ==="); if (!validateRecipient(recipient)) { System.out.println("❌ Invalid recipient: " + recipient); return; } try { sendNotification(message, recipient); logNotification("SUCCESS", recipient); } catch (Exception e) { System.out.println("❌ Failed to send notification: " + e.getMessage()); logNotification("FAILED", recipient); } } private void logNotification(String status, String recipient) { System.out.println(" 📊 Log: " + name() + " notification " + status + " to " + recipient + " at " + java.time.LocalTime.now()); } } public class ConstantSpecificMethodsDemo { public static void main(String[] args) { System.out.println("=== ENUM WITH CONSTANT-SPECIFIC METHODS ==="); // Operation enum demonstration System.out.println("\n=== OPERATION ENUM DEMO ==="); double x = 10, y = 3; for (Operation op : Operation.values()) { try { double result = op.apply(x, y); System.out.printf("%.1f %s %.1f = %.2f%n", x, op, y, result); } catch (ArithmeticException e) { System.out.printf("%.1f %s %.1f = ERROR: %s%n", x, op, y, e.getMessage()); } } // Calculator simulation System.out.println("\n=== CALCULATOR SIMULATION ==="); String[] expressions = {"5 + 3", "10 - 4", "6 * 7", "15 / 3", "8 / 0", "2 ^ 8"}; for (String expression : expressions) { String[] parts = expression.split(" "); double a = Double.parseDouble(parts[0]); double b = Double.parseDouble(parts[2]); Operation op = Operation.valueOf(parts[1].toUpperCase()); try { double result = op.apply(a, b); System.out.printf("%s = %.2f%n", expression, result); } catch (ArithmeticException e) { System.out.printf("%s = ERROR: %s%n", expression, e.getMessage()); } } // FileType enum demonstration System.out.println("\n=== FILE TYPE PROCESSING ==="); String[] filenames = {"document.txt", "data.json", "config.xml", "records.csv", "image.png"}; for (String filename : filenames) { System.out.println("\nProcessing: " + filename); try { FileType fileType = FileType.fromFilename(filename); String sampleContent = getSampleContent(fileType); fileType.process(sampleContent); } catch (IllegalArgumentException e) { System.out.println(" ❌ " + e.getMessage()); } } // NotificationChannel enum demonstration System.out.println("\n=== NOTIFICATION SYSTEM ==="); String message = "Hello! This is an important notification from our system."; NotificationChannel.EMAIL.sendSecureNotification(message, "[email protected]"); NotificationChannel.SMS.sendSecureNotification(message, "+1234567890"); NotificationChannel.PUSH.sendSecureNotification(message, "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6"); System.out.println("\n=== INVALID NOTIFICATIONS ==="); NotificationChannel.EMAIL.sendSecureNotification(message, "invalid-email"); NotificationChannel.SMS.sendSecureNotification(message, "123"); NotificationChannel.PUSH.sendSecureNotification(message, "short-token"); } private static String getSampleContent(FileType fileType) { switch (fileType) { case TEXT: return "This is a sample text file content."; case JSON: return "{\"name\": \"John\", \"age\": 30, \"city\": \"New York\"}"; case XML: return "<user><name>John</name><age>30</age><city>New York</city></user>"; case CSV: return "Name,Age,City\nJohn,30,New York\nJane,25,Los Angeles\nBob,35,Chicago"; default: return "Unknown content"; } } }

Output:

=== ENUM WITH CONSTANT-SPECIFIC METHODS === === OPERATION ENUM DEMO === 10.0 + 3.0 = 13.00 10.0 - 3.0 = 7.00 10.0 * 3.0 = 30.00 10.0 / 3.0 = 3.33 10.0 ^ 3.0 = 1000.00 10.0 % 3.0 = 1.00 === CALCULATOR SIMULATION === 5 + 3 = 8.00 10 - 4 = 6.00 6 * 7 = 42.00 15 / 3 = 5.00 8 / 0 = ERROR: Division by zero! 2 ^ 8 = 256.00 === FILE TYPE PROCESSING === Processing: document.txt Processing text file: This is a sample text file content. Processing: data.json Parsing JSON: {"name": "John", "age": 30, "city": "New York"} ✓ Valid JSON structure Processing: config.xml Parsing XML: <user><name>John</name><age>30</age><city>New York</city></user> ✓ Valid XML structure Processing: records.csv Processing CSV: Name,Age,City John,30,New York Jane,25,Los Angeles Bob,35,Chicago Found 4 rows Row 1: Name,Age,City Row 2: John,30,New York Row 3: Jane,25,Los Angeles Processing: image.png ❌ Unknown file type: image.png === NOTIFICATION SYSTEM === === Sending Secure Notification === 📧 Sending email to: [email protected] Subject: Notification Body: Hello! This is an important notification from our system. → Email sent successfully! 📊 Log: EMAIL notification SUCCESS to [email protected] at 10:30:45.123 === Sending Secure Notification === 📱 Sending SMS to: +1234567890 Message: Hello! This is an imp... → SMS sent successfully! 📊 Log: SMS notification SUCCESS to +1234567890 at 10:30:45.124 === Sending Secure Notification === 📲 Sending push notification to device: a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6 Title: App Notification Body: Hello! This is an important notification from our system. → Push notification sent! 📊 Log: PUSH notification SUCCESS to a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6 at 10:30:45.124 === INVALID NOTIFICATIONS === === Sending Secure Notification === ❌ Invalid recipient: invalid-email === Sending Secure Notification === ❌ Invalid recipient: 123 === Sending Secure Notification === ❌ Invalid recipient: short-token

Example 4: Real-World Enum Usage Patterns

import java.time.DayOfWeek; import java.time.LocalDate; // ✅ REAL-WORLD ENUM USAGE PATTERNS // Configuration enum enum Environment { DEVELOPMENT("dev", "http://localhost:8080", true), TESTING("test", "http://test.example.com", true), STAGING("staging", "http://staging.example.com", false), PRODUCTION("prod", "https://example.com", false); private final String code; private final String baseUrl; private final boolean debugEnabled; Environment(String code, String baseUrl, boolean debugEnabled) { this.code = code; this.baseUrl = baseUrl; this.debugEnabled = debugEnabled; } public String getCode() { return code; } public String getBaseUrl() { return baseUrl; } public boolean isDebugEnabled() { return debugEnabled; } public static Environment fromCode(String code) { for (Environment env : values()) { if (env.code.equalsIgnoreCase(code)) { return env; } } throw new IllegalArgumentException("Unknown environment: " + code); } public String getDatabaseUrl() { return baseUrl.replace("http", "jdbc:postgresql") + "/" + code + "_db"; } } // State machine enum enum OrderStatus { PENDING { @Override public OrderStatus next() { return CONFIRMED; } @Override public boolean canCancel() { return true; } }, CONFIRMED { @Override public OrderStatus next() { return PROCESSING; } @Override public boolean canCancel() { return true; } }, PROCESSING { @Override public OrderStatus next() { return SHIPPED; } @Override public boolean canCancel() { return false; } }, SHIPPED { @Override public OrderStatus next() { return DELIVERED; } @Override public boolean canCancel() { return false; } }, DELIVERED { @Override public OrderStatus next() { return this; } // Final state @Override public boolean canCancel() { return false; } }, CANCELLED { @Override public OrderStatus next() { return this; } // Final state @Override public boolean canCancel() { return false; } }; public abstract OrderStatus next(); public abstract boolean canCancel(); public boolean isFinalState() { return this == DELIVERED || this == CANCELLED; } } // Permission enum with bit flags enum Permission { READ(1), // 0001 WRITE(2), // 0010 EXECUTE(4), // 0100 DELETE(8); // 1000 private final int value; Permission(int value) { this.value = value; } public int getValue() { return value; } public static int combine(Permission... permissions) { int result = 0; for (Permission permission : permissions) { result |= permission.value; } return result; } public static boolean hasPermission(int permissions, Permission permission) { return (permissions & permission.value) != 0; } public static String describePermissions(int permissions) { StringBuilder sb = new StringBuilder(); for (Permission perm : values()) { if (hasPermission(permissions, perm)) { if (sb.length() > 0) sb.append(", "); sb.append(perm.name()); } } return sb.toString(); } } // Singleton pattern with enum (Joshua Bloch's preferred method) enum DatabaseConnection { INSTANCE; private boolean connected = false; public void connect() { if (!connected) { System.out.println("🔗 Connecting to database..."); // Simulate connection logic try { Thread.sleep(1000); } catch (InterruptedException e) {} connected = true; System.out.println("✅ Database connected successfully!"); } else { System.out.println("ℹ️ Database already connected"); } } public void disconnect() { if (connected) { System.out.println("🔌 Disconnecting from database..."); connected = false; System.out.println("✅ Database disconnected"); } else { System.out.println("ℹ️ Database already disconnected"); } } public void executeQuery(String query) { if (!connected) { throw new IllegalStateException("Database not connected"); } System.out.println("📊 Executing query: " + query); // Simulate query execution } } public class RealWorldEnumPatterns { public static void main(String[] args) { System.out.println("=== REAL-WORLD ENUM USAGE PATTERNS ==="); // Environment configuration System.out.println("\n=== ENVIRONMENT CONFIGURATION ==="); Environment currentEnv = Environment.DEVELOPMENT; System.out.println("Current Environment: " + currentEnv); System.out.println("Base URL: " + currentEnv.getBaseUrl()); System.out.println("Database URL: " + currentEnv.getDatabaseUrl()); System.out.println("Debug enabled: " + currentEnv.isDebugEnabled()); System.out.println("\nAll environments:"); for (Environment env : Environment.values()) { System.out.printf(" %-10s: %-25s | Debug: %-5s | DB: %s%n", env.name(), env.getBaseUrl(), env.isDebugEnabled(), env.getDatabaseUrl()); } // Lookup by code System.out.println("\nLooking up by code:"); System.out.println("'prod' -> " + Environment.fromCode("prod")); // Order status state machine System.out.println("\n=== ORDER STATUS STATE MACHINE ==="); OrderStatus status = OrderStatus.PENDING; System.out.println("Initial status: " + status); while (!status.isFinalState()) { System.out.println("Current: " + status + " | Can cancel: " + status.canCancel() + " | Next: " + status.next()); status = status.next(); } System.out.println("Final status: " + status); // Simulate order processing System.out.println("\n=== ORDER PROCESSING SIMULATION ==="); simulateOrderProcessing(); // Permission system with bit flags System.out.println("\n=== PERMISSION SYSTEM ==="); int userPermissions = Permission.combine(Permission.READ, Permission.WRITE); int adminPermissions = Permission.combine(Permission.READ, Permission.WRITE, Permission.EXECUTE, Permission.DELETE); System.out.println("User permissions: " + userPermissions + " (" + Integer.toBinaryString(userPermissions) + ")"); System.out.println("User can READ: " + Permission.hasPermission(userPermissions, Permission.READ)); System.out.println("User can EXECUTE: " + Permission.hasPermission(userPermissions, Permission.EXECUTE)); System.out.println("User permissions: " + Permission.describePermissions(userPermissions)); System.out.println("Admin permissions: " + adminPermissions + " (" + Integer.toBinaryString(adminPermissions) + ")"); System.out.println("Admin permissions: " + Permission.describePermissions(adminPermissions)); // Singleton pattern with enum System.out.println("\n=== DATABASE CONNECTION SINGLETON ==="); DatabaseConnection db1 = DatabaseConnection.INSTANCE; DatabaseConnection db2 = DatabaseConnection.INSTANCE; System.out.println("db1 == db2: " + (db1 == db2)); // Same instance db1.connect(); db2.connect(); // Should show already connected db1.executeQuery("SELECT * FROM users"); db1.disconnect(); // Enum in business logic System.out.println("\n=== BUSINESS LOGIC WITH ENUMS ==="); processWeekdayBusiness(DayOfWeek.MONDAY); processWeekdayBusiness(DayOfWeek.SATURDAY); } private static void simulateOrderProcessing() { OrderStatus status = OrderStatus.PENDING; System.out.println("Order created with status: " + status); // Process order through states String[] actions = {"confirm", "process", "ship", "deliver"}; for (String action : actions) { if (status.isFinalState()) break; System.out.println("\nAction: " + action.toUpperCase()); if (action.equals("cancel") && status.canCancel()) { status = OrderStatus.CANCELLED; System.out.println("Order cancelled!"); } else { status = status.next(); System.out.println("Order status: " + status); } System.out.println("Can cancel: " + status.canCancel()); System.out.println("Is final: " + status.isFinalState()); } } private static void processWeekdayBusiness(DayOfWeek day) { System.out.println("\nProcessing business for: " + day); switch (day) { case MONDAY: System.out.println(" 📊 Weekly planning meeting"); System.out.println(" 📈 Review metrics from last week"); break; case FRIDAY: System.out.println(" 🎉 Team lunch"); System.out.println(" 📋 Week in review meeting"); break; case SATURDAY: case SUNDAY: System.out.println(" 🏖️ Weekend - no business activities"); break; default: System.out.println(" 💼 Regular work day"); System.out.println(" 📝 Daily standup meeting"); } // Check if it's a workday if (day.getValue() >= DayOfWeek.MONDAY.getValue() && day.getValue() <= DayOfWeek.FRIDAY.getValue()) { System.out.println(" ✅ Business hours: 9 AM - 5 PM"); } else { System.out.println(" ❌ Closed - weekend"); } } }

Output:

=== REAL-WORLD ENUM USAGE PATTERNS === === ENVIRONMENT CONFIGURATION === Current Environment: DEVELOPMENT Base URL: http://localhost:8080 Database URL: jdbc:postgresql://localhost:8080/dev_db Debug enabled: true All environments: DEVELOPMENT: http://localhost:8080 | Debug: true | DB: jdbc:postgresql://localhost:8080/dev_db TESTING : http://test.example.com | Debug: true | DB: jdbc:postgresql://test.example.com/test_db STAGING : http://staging.example.com | Debug: false | DB: jdbc:postgresql://staging.example.com/staging_db PRODUCTION : https://example.com | Debug: false | DB: jdbc:postgresql://example.com/prod_db Looking up by code: 'prod' -> PRODUCTION === ORDER STATUS STATE MACHINE === Initial status: PENDING Current: PENDING | Can cancel: true | Next: CONFIRMED Current: CONFIRMED | Can cancel: true | Next: PROCESSING Current: PROCESSING | Can cancel: false | Next: SHIPPED Current: SHIPPED | Can cancel: false | Next: DELIVERED Final status: DELIVERED === ORDER PROCESSING SIMULATION === Order created with status: PENDING Action: CONFIRM Order status: CONFIRMED Can cancel: true Is final: false Action: PROCESS Order status: PROCESSING Can cancel: false Is final: false Action: SHIP Order status: SHIPPED Can cancel: false Is final: false Action: DELIVER Order status: DELIVERED Can cancel: false Is final: true === PERMISSION SYSTEM === User permissions: 3 (11) User can READ: true User can EXECUTE: false User permissions: READ, WRITE Admin permissions: 15 (1111) Admin permissions: READ, WRITE, EXECUTE, DELETE === DATABASE CONNECTION SINGLETON === db1 == db2: true 🔗 Connecting to database... ✅ Database connected successfully! ℹ️ Database already connected 📊 Executing query: SELECT * FROM users 🔌 Disconnecting from database... ✅ Database disconnected === BUSINESS LOGIC WITH ENUMS === Processing business for: MONDAY 📊 Weekly planning meeting 📈 Review metrics from last week ✅ Business hours: 9 AM - 5 PM Processing business for: SATURDAY 🏖️ Weekend - no business activities ❌ Closed - weekend

Enum Declaration Syntax

Basic Syntax:

enum EnumName { CONSTANT1, CONSTANT2, CONSTANT3; }

With Fields and Methods:

enum EnumName { CONSTANT1(value1), CONSTANT2(value2); private FieldType field; EnumName(FieldType field) { this.field = field; } public FieldType getField() { return field; } }

With Constant-Specific Methods:

enum EnumName { CONSTANT1 { public ReturnType method() { /* implementation */ } }, CONSTANT2 { public ReturnType method() { /* implementation */ } }; public abstract ReturnType method(); }

Best Practices

✅ When to Use Enums:

  1. Fixed set of constants - Days, status codes, colors
  2. Type-safe alternatives - Instead of string/integer constants
  3. Singleton pattern - Single instance enforcement
  4. Strategy pattern - Different behaviors for each constant
  5. State machines - Defined state transitions

✅ Enum Design Principles:

  1. Use descriptive names - HTTPStatus.OK not HTTPStatus.STATUS200
  2. Include useful methods - Validation, conversion, behavior
  3. Consider immutability - Make fields final
  4. Override toString() - For meaningful string representation
  5. Provide valueOf() alternatives - For custom parsing

✅ Performance Benefits:

  • == comparison - Faster than equals()
  • Switch statements - Optimized by compiler
  • Memory efficient - Single instances, no duplication
  • Thread-safe - Naturally immutable

Common Pitfalls

// ❌ BAD: Using strings instead of enums String status = "pending"; // What if someone types "pendng"? // ✅ GOOD: Using enums enum OrderStatus { PENDING, CONFIRMED, SHIPPED } OrderStatus status = OrderStatus.PENDING; // ❌ BAD: Not handling unknown values enum Color { RED, GREEN, BLUE } // How to handle "YELLOW"? // ✅ GOOD: Provide fromString with default public static Color fromString(String color) { try { return Color.valueOf(color.toUpperCase()); } catch (IllegalArgumentException e) { return UNKNOWN; // Or throw custom exception } }

Conclusion

Enum types are Java's super-powered constants:

  • Type-safe - Compiler prevents invalid values
  • Rich functionality - Fields, methods, constructors
  • Object-oriented - Full class capabilities
  • Performance optimized - Fast comparisons and switches
  • Thread-safe - Immutable by nature

Key Takeaways:

  • Use enums instead of string/integer constants for type safety
  • Leverage enum capabilities - fields, methods, constant-specific behaviors
  • Consider enums for design patterns - Singleton, Strategy, State
  • Override toString() for meaningful representations
  • Use EnumSet and EnumMap for enum-specific collections

Enums transform what would be error-prone string/integer constants into robust, self-documenting, and powerful constructs that make your code safer, cleaner, and more maintainable!

Leave a Reply

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


Macro Nepal Helper