Java
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented Java
-
Section 4: Collections Framework
-
Section 5: Exception Handling
-
Section 6: Generics
-
Section 7: Functional Java
-
Section 8: Concurrency
-
Section 9: I/O and NIO
-
Section 10: JVM Internals
-
Section 11: Modern Java Features
-
Section 12: Build Tools and Project Structure
-
Section 13: Testing
-
Section 14: Databases and Persistence
-
Section 15: Networking
-
Section 16: Design and Best Practices
-
Section 17: Reflection and Annotations
-
Section 18: Logging and Diagnostics
-
Section 19: Date, Time, and Internationalization
-
Section 20: Java Platform Module System
-
Section 21: Security in Java
-
Section 22: Advanced Collections and Data Structures
-
Section 23: More Concurrency Patterns
-
Section 24: Compression, Files, and System Integration
-
Section 25: GUI Programming
-
Section 26: Practical Projects
-
Section 27: Data Structures and Algorithms
-
Section 28: Interview and Algorithm Practice
-
Section 29: JSON and Data Interchange
-
Section 30: More Concurrency Utilities
-
Section 31: More Collections and Streams Practice
-
Section 32: More File and System Programming
-
Section 33: Standard Library Deep Dive
-
Section 34: More Practice and Drills
-
Section 35: More Testing and Quality
-
Section 36: More Design Patterns and Architecture
-
Section 37: Career and Ecosystem
-
Section 38: More OOP and Architecture Practice
-
Section 39: More Enterprise Concepts
-
Section 40: Advanced JavaFX
-
Section 41: More Interview Practice
35: Enums in Depth
If you're coming from C++ or C#, your first instinct might be that Java's enum is just a glorified way to group a few static final int values together. I see this all the time with developers who treat enums as simple labels. They think of them as a replacement for public static final String STATUS_PENDING = "PENDING";.
Here is why that's a mistake: in Java, an enum is not a constant; it is a class. It's a special kind of class that happens to have a fixed set of instances, but it has all the power of any other Java class. If you treat them as just labels, you're missing out on the best part of the language's type system.
Stop thinking of Enums as labels; start thinking of them as objects
When you define an enum, you aren't just making a list. You are defining a type. Let's look at a common scenario: shipping methods. A beginner might just do this:
public enum ShippingMethod {
GROUND, AIR, SEA
}
That works, but it's anemic. Usually, a shipping method isn't just a name; it has a cost and a delivery window. Instead of writing a giant switch statement somewhere else in your code to map GROUND to a price, you should put that data directly inside the enum. I always tell my juniors: "Keep the data with the definition."
public enum ShippingMethod {
GROUND(5.00, 5),
AIR(20.00, 1),
SEA(2.00, 20);
private final double baseCost;
private final int estimatedDays;
// The constructor is private by default; you can't call it from outside.
ShippingMethod(double baseCost, int estimatedDays) {
this.baseCost = baseCost;
this.estimatedDays = estimatedDays;
}
public double calculateCost(double weight) {
return baseCost + (weight * 0.50);
}
public int getEstimatedDays() {
return estimatedDays;
}
}
Now, the ShippingMethod isn't just a tag; it's a business object. You've encapsulated the logic for cost calculation inside the enum itself. This means if you add a DRONE method later, you're forced to define its cost and days right there, rather than hunting down every if/else block in your project.
Giving constants their own unique behavior
Now, here is where things get really interesting. Sometimes, a simple field isn't enough because different constants need to behave differently. You might think you need a complex inheritance hierarchy for this, but Java lets you define abstract methods inside an enum.
Imagine we are building a simple calculator for different mathematical operations. We want each operation to "know" how to execute itself. I personally love this pattern because it completely eliminates the need for messy switch statements in your service layer.
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; }
};
// Every constant MUST implement this method
public abstract double apply(double x, double y);
}
Notice how each constant is essentially an anonymous inner class that extends Operation. You can now call Operation.ADD.apply(10, 5) and get 15. The logic is decoupled from the caller and tied directly to the constant.
The "gotchas" of Enum identity
One last thing to keep in mind: because enums are singletons, you should always compare them using == instead of .equals(). While .equals() works, == is null-safe and slightly faster. If you try to compare method == ShippingMethod.GROUND, it will never throw a NullPointerException even if method is null; it'll just return false. It's a small detail, but it's the mark of someone who actually knows how Java handles these under the hood.
📋 Practical Task
Building a Subscription Tier Pricing Engine
You are tasked with creating a subscription management system for a SaaS product. Instead of using a series of if statements to check user tiers, you will implement a robust SubscriptionTier enum.
Requirements:
- Create an enum named
SubscriptionTierwith three constants:BASIC,PRO, andENTERPRISE. - Each tier must have a
monthlyPrice(double) and amaxUsers(int) assigned via a constructor. - Implement an abstract method
calculateDiscountedPrice(double percentage). - Custom Logic:
- The
BASICtier should not allow any discounts (it always returns the full price). - The
PROandENTERPRISEtiers should apply the percentage discount to the monthly price.
- The
- Write a
mainmethod to demonstrate that callingSubscriptionTier.BASIC.calculateDiscountedPrice(0.20)returns the original price, whileSubscriptionTier.PRO.calculateDiscountedPrice(0.20)returns the price minus 20%.
There are no comments for now.