Java Records, Enums and Optional
Java records, enums and Optional are modern features that remove a lot of boilerplate and make your intent clearer. Records model plain data, enums model a fixed set of choices, and Optional models a value that may be missing.
Records
A record (Java 16+) is a compact, immutable data class. From one line, Java generates the constructor, accessor methods, equals, hashCode and toString. A compact constructor can validate the data.
record Point(int x, int y) {
Point {
if (x < 0 || y < 0) throw new IllegalArgumentException("negative");
}
double distanceFromOrigin() {
return Math.sqrt(x * x + y * y);
}
}
public class Main {
public static void main(String[] args) {
var p = new Point(3, 4);
System.out.println(p);
System.out.println(p.x() + ", " + p.y());
System.out.println(p.distanceFromOrigin());
System.out.println(p.equals(new Point(3, 4)));
}
}Point[x=3, y=4] 3, 4 5.0 true
Enums
An enum defines a fixed set of named constants. Enums are full classes, so they can have fields, constructors and methods, and they work perfectly with switch.
enum Size {
SMALL(250), MEDIUM(350), LARGE(500);
private final int ml;
Size(int ml) { this.ml = ml; }
int ml() { return ml; }
}
public class Main {
public static void main(String[] args) {
Size s = Size.MEDIUM;
System.out.println(s + " = " + s.ml() + " ml");
String price = switch (s) {
case SMALL -> "Rs 300";
case MEDIUM -> "Rs 400";
case LARGE -> "Rs 550";
};
System.out.println(price);
for (Size each : Size.values()) System.out.print(each.ordinal() + ":" + each + " ");
System.out.println();
System.out.println(Size.valueOf("LARGE").ml());
}
}MEDIUM = 350 ml Rs 400 0:SMALL 1:MEDIUM 2:LARGE 500
Optional
Optional is a container that holds a value or nothing. Returning Optional instead of null forces callers to think about the missing case.
import java.util.Map;
import java.util.Optional;
public class Main {
static final Map<Integer, String> USERS = Map.of(1, "naeem", 2, "sara");
static Optional<String> findUser(int id) {
return Optional.ofNullable(USERS.get(id));
}
public static void main(String[] args) {
System.out.println(findUser(1).map(String::toUpperCase).orElse("guest"));
System.out.println(findUser(9).map(String::toUpperCase).orElse("guest"));
findUser(2).ifPresent(u -> System.out.println("Found " + u));
System.out.println(findUser(9).isEmpty());
}
}NAEEM guest Found sara true
Pattern Matching for switch (Java 21)
Java 21 lets switch test types and deconstruct records directly, with optional when guards. This replaces long instanceof chains.
record Circle(double r) {}
record Rect(double w, double h) {}
public class Main {
static String describe(Object shape) {
return switch (shape) {
case Circle(double r) when r == 0 -> "a dot";
case Circle(double r) -> "circle with area %.1f".formatted(Math.PI * r * r);
case Rect(double w, double h) when w == h -> "square of side " + w;
case Rect(double w, double h) -> "rectangle " + w + "x" + h;
case null -> "nothing";
default -> "unknown shape";
};
}
public static void main(String[] args) {
System.out.println(describe(new Circle(2)));
System.out.println(describe(new Rect(3, 3)));
System.out.println(describe(new Rect(2, 5)));
System.out.println(describe(null));
}
}circle with area 12.6 square of side 3.0 rectangle 2.0x5.0 nothing
Frequently asked questions
What is the difference between a record and a class in Java?
A record is a special class for immutable data. Its fields are final, and Java generates the constructor, accessors, equals, hashCode and toString. A record cannot extend another class.
Can a Java enum have methods?
Yes. Enums can have fields, constructors, methods, and can even implement interfaces. Each constant can also override a method.
When should I use Optional in Java?
Use it as a return type for methods that might not find a result. Avoid using it for fields or method parameters, where it adds noise without much benefit.