Enums & Records — Type-Safe Constants & Data Without Boilerplate
Enum ও Record — type-safe ধ্রুবক ও boilerplate-মুক্ত ডেটা
1. Two Modern Shortcuts
Two common shapes of type come up so often that Java gives them their own keyword:
- Enum — a fixed, named set of instances.
DayOfWeek,PaymentMethod,OrderStatus. Type-safe, self-documenting, and far safer than a bunch ofintconstants. - Record (Java 14+) — a class whose whole purpose is to carry immutable data. One line
gives you fields, constructor, accessors,
equals,hashCode, andtoString.
2. Enums — More Than Named Integers
A Java enum is actually a full class under the hood. Each constant is a singleton instance, and the enum can carry fields, a constructor, and methods — including abstract methods that each constant overrides.
enum MobileOperator {
GP("Grameenphone", "017"),
ROBI("Robi", "018"),
BANGLALINK("Banglalink", "019"),
TELETALK("Teletalk", "015");
private final String fullName;
private final String prefix;
MobileOperator(String fullName, String prefix) {
this.fullName = fullName;
this.prefix = prefix;
}
public String fullName() { return fullName; }
public String prefix() { return prefix; }
}
class Main {
public static void main(String[] args) {
for (MobileOperator op : MobileOperator.values()) {
System.out.println(op.fullName() + " → prefix " + op.prefix());
}
}
}
HashSet<MobileOperator> when
the keys are enum constants.
EnumSet ও EnumMap — enum-এর জন্য অনুকূলিত। Internally bit-set বা array ব্যবহার করে, তাই HashSet/HashMap-এর চেয়ে দ্রুত ও কম মেমোরি।
3. Records — One Line Replaces Forty
Before Java 14 an immutable "data" class needed private final fields, a constructor, getters,
equals, hashCode, toString — easily 40 lines for three fields. A
record gives you all of that, correctly implemented, in one line.
record Point(int x, int y) {}
record Student(String name, double cgpa) {
// Compact constructor — validate before fields are assigned
Student {
if (cgpa < 0 || cgpa > 4)
throw new IllegalArgumentException("CGPA out of range");
}
}
class Main {
public static void main(String[] args) {
Point p = new Point(2, 3);
System.out.println(p); // Point[x=2, y=3] — auto toString
System.out.println(p.x() + "," + p.y()); // accessors are x()/y(), not getX()/getY()
Student s = new Student("Maya", 3.8);
System.out.println(s); // Student[name=Maya, cgpa=3.8]
System.out.println(p.equals(new Point(2, 3))); // true — value equality
}
}
private final হয়, নামের সাথে একই accessor method থাকে (x(), y())। Compact constructor দিয়ে validation করা যায়। equals, hashCode, toString compiler নিজেই সঠিকভাবে generate করে — value-based equality।
4. When to Use a Record (and When Not To)
Records shine for transparent data carriers — objects whose identity is their data: DTOs, API request/response shapes, cache keys, coordinates, tuples. Do not pick a record if you need mutable state, an inheritance hierarchy beyond Object, or fields that are conceptually hidden.
✅ Record fits
- Immutable DTO / value object
- Cache keys (free correct equals/hashCode)
- Tuples:
Pair<A,B>,Triple<A,B,C> - Request/response shapes for REST APIs
⚠️ Use a regular class
- State mutates over time (accounts, sessions)
- You need to hide internal representation
- You need to extend another class
- Complex invariants across multiple methods
5. Enums + switch Expressions
Enums compose beautifully with modern switch expressions — every case returns a value, and the compiler insists the switch is exhaustive. Add a new constant and the compiler hunts down every switch that needs updating.
enum OrderStatus { NEW, PACKED, SHIPPED, DELIVERED, CANCELLED }
class Main {
static String describe(OrderStatus s) {
return switch (s) {
case NEW -> "Just placed";
case PACKED -> "Ready to ship";
case SHIPPED -> "On the way";
case DELIVERED -> "Arrived";
case CANCELLED -> "Cancelled";
};
}
public static void main(String[] args) {
System.out.println(describe(OrderStatus.SHIPPED));
}
}
6. Vocabulary (শব্দভাণ্ডার)
| Term | Meaning | বাংলায় |
|---|---|---|
enum | A fixed, named set of class instances. | নির্দিষ্ট, নামকরা কয়েকটি instance। |
values() | Auto-generated array of all enum constants. | সব enum constant-এর auto array। |
| EnumSet | Bit-set optimised set for enum keys. | Enum-এর জন্য bit-set optimised set। |
| EnumMap | Array-backed map with enum keys. | Enum key-যুক্ত array-backed map। |
record | Transparent immutable data class (Java 14+). | Transparent immutable data class (Java 14+)। |
| Component | Record's data field; accessor has the same name. | Record-এর ডেটা field; accessor-ও একই নাম। |
| Compact constructor | Record constructor without parameter list; for validation. | Parameter list ছাড়া record constructor; validation-এর জন্য। |
7. Practice Problems
-
Declare an
enum Currencywith BDT, USD, EUR and adouble rateToBdtfield. Convert 100 USD to BDT using a method.Currencyenum (BDT, USD, EUR) বানান — প্রতিটিরrateToBdtfield থাকবে। 100 USD কে BDT-তে রূপান্তর দেখান।✨ Show Answer
Main.javaenum Currency { BDT(1.0), USD(118.0), EUR(128.0); final double rateToBdt; Currency(double r) { rateToBdt = r; } double toBdt(double amount) { return amount * rateToBdt; } } class Main { public static void main(String[] args) { System.out.println("100 USD = " + Currency.USD.toBdt(100) + " BDT"); } } -
Define
record Movie(String title, int year). Create two identical movies and print whetherequalsreturns true.record Movie(String title, int year)বানান। দুটি একই movie তৈরি করুন ওequalstrue কিনা প্রিন্ট করুন।✨ Show Answer
Main.javarecord Movie(String title, int year) {} class Main { public static void main(String[] args) { Movie a = new Movie("Matir Moina", 2002); Movie b = new Movie("Matir Moina", 2002); System.out.println(a.equals(b)); } } -
List three things Java generates for you when you declare a record.Record ঘোষণা করলে Java কী কী auto-generate করে — তিনটি বলুন।
✨ Show Answer
Answer:
- A canonical constructor matching the header, and a
private finalfield for each component. - An accessor method per component (same name as the component, e.g.
x()). - Correct value-based
equals,hashCode, and a readabletoString.
Canonical constructor ও private final field; প্রতিটি component-এর accessor; সঠিক equals/hashCode/toString।
- A canonical constructor matching the header, and a
-
Write an enum
TrafficLightwith an abstract methodaction(), overridden per constant to print what to do.TrafficLightenum বানান — abstractaction()method, প্রতিটি constant-এ override করে কী করতে হবে print করবে।✨ Show Answer
Main.javaenum TrafficLight { RED { void action() { System.out.println("Stop"); } }, YELLOW { void action() { System.out.println("Slow"); } }, GREEN { void action() { System.out.println("Go"); } }; abstract void action(); } class Main { public static void main(String[] args) { for (TrafficLight l : TrafficLight.values()) l.action(); } } -
Why is a record always a poor replacement for a JavaBean-style mutable class? Two sentences.দুই বাক্যে — mutable JavaBean-এর বদলে record ব্যবহার কেন উপযুক্ত নয়?
✨ Show Answer
Answer: A record is immutable by design — every component becomes a
private finalfield and no setters are generated. If you need state that evolves over the object's life, you need a regular class with setters or explicit update methods.Record সবসময় immutable — field
private final, setter নেই। State-কে সময়ের সাথে বদলাতে হলে সাধারণ class + setter দরকার।
Summary — Module 17
An enum is a first-class type for a fixed set of instances — it can carry fields, methods,
and even per-constant behaviour, and it pairs perfectly with exhaustive switch expressions.
A record (Java 14+) is a transparent, immutable carrier of data: one line of declaration
gives you the fields, the constructor, accessors, and correct equals, hashCode,
and toString. Use enums where "it's one of these"; use records for "it's just this data."
switch-এ দারুণ মানিয়ে যায়। Record (Java 14+) transparent immutable ডেটা carrier — এক লাইনে field, constructor, accessor, equals/hashCode/toString পাওয়া যায়। "এটি কয়েকটির একটি" হলে enum, "এটি শুধু একগুচ্ছ ডেটা" হলে record।