Java 17 Features
Java 17 (September 2021) is the second major LTS (Long-Term Support) release after Java 11 — many companies migrate straight to this version because it bundles several years of improvements at once (every feature from Java 12 through 17).
The biggest highlights: Records (data classes in one line), Sealed Classes (controlled inheritance), Pattern Matching for instanceof (auto-casting), Text Blocks (multi-line strings made easy), and Switch Expressions.
Java 17 features come up a lot in interviews, especially Records and Sealed Classes — because they change the way modern Java code gets written, cutting down on boilerplate.
// Record — ek line mein data class
record User(String name, int age) {}
User u = new User("Aarav", 25);
System.out.println(u); // User[name=Aarav, age=25]
// Pattern Matching for instanceof
Object obj = "Hello";
if (obj instanceof String s) {
System.out.println(s.length()); // seedha use, cast nahi chahiye
}- Java 17 = LTS release (Sept 2021)
- Records = data classes in one line
- Sealed Classes = controlled inheritance
- Pattern Matching for instanceof = auto-cast
- Text Blocks = multi-line strings made easy
Creating a simple data-holder class (like a Point with just x and y) in a normal class means writing a lot of boilerplate — a constructor, getters, equals(), hashCode(), toString(), all by hand (or generated by an IDE). The record keyword generates all of this automatically in one line.
Writing record Point(int x, int y) {} makes the compiler generate: a constructor (that sets both fields), getter methods (x() and y() — no "get" prefix), and properly implemented equals(), hashCode(), toString(). Records are implicitly final (can't be extended), and their fields are implicitly final too (immutable).
Records are best when you just need to carry data, with no complex behavior — like API responses, DTOs (Data Transfer Objects), or coordinate pairs. If a class needs methods/logic too (not just data), a normal class is still the better fit.
An interviewer might ask about the difference between records and Lombok's @Data annotation — Lombok is a third-party library that generates code at compile time (via annotation processing), while records are a native language feature, so no extra dependency is needed.
- Constructor — sets both fields, automatically
- Getters — x() and y(), no "get" prefix
- equals() / hashCode() — compare values, properly implemented
- toString() — readable format, like Point[x=3, y=4]
record Point(int x, int y) {}
Point p1 = new Point(3, 4);
System.out.println(p1.x()); // 3 (getter, "get" prefix nahi)
System.out.println(p1); // Point[x=3, y=4] (auto toString)
Point p2 = new Point(3, 4);
System.out.println(p1.equals(p2)); // true (auto equals, values compare hote hain)Anyone can normally extend/implement a class/interface — the sealed keyword lets you control *exactly* who's allowed to extend/implement it. This is especially useful when you know upfront exactly what all the possible subtypes are (like a Shape that can only be Circle, Square, or Triangle, and nothing else).
Writing sealed class Shape permits Circle, Square, Triangle {} means only these three classes can extend Shape — no outside code can create a new subtype. Every permitted subclass has to explicitly declare itself: final (can't be extended further), sealed (controls its own further extension), or non-sealed (back to normal, anyone can extend it).
The benefit: in switch statements, the compiler knows exactly what all the possible types are, so "exhaustiveness checking" becomes possible (we'll see this with pattern matching in the next subtopic) — the compiler can confirm every case is covered even without a default case.
A real-world use-case: sealed classes are great for modeling API responses — like an ApiResult that can only be a Success or a Failure, nothing else. This pattern is inspired by functional languages (like Kotlin's sealed classes).
- final — a permitted subclass can't be extended further
- sealed — a permitted subclass controls its own further extension
- non-sealed — back to normal, anyone can extend it
sealed interface Shape permits Circle, Square, Triangle {}
final class Circle implements Shape { double radius; }
final class Square implements Shape { double side; }
final class Triangle implements Shape { double base, height; }
// Koi doosri class Shape implement NAHI kar sakti — compiler error degaIn older Java, after an instanceof check you had to manually cast — two steps, a bit repetitive: if (obj instanceof String) { String s = (String) obj; ... }. In Java 16+ (stable in 17), instanceof can now "bind" a variable itself if the check passes.
Writing if (obj instanceof String s) means that if obj is a String, s automatically points to that already-cast value — you can use s directly inside that if block, no manual cast needed. This makes code shorter and safer (less risk of a ClassCastException, since the compiler itself does the type-check).
It's also useful in chained conditions — you can write if (obj instanceof String s && s.length() > 5), where the pattern variable s is immediately usable in the next condition too.
Object obj = "Hello Java 17";
// Purana tareeka:
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// Java 16+ pattern matching:
if (obj instanceof String s) {
System.out.println(s.length()); // s seedha use ho sakta hai, cast nahi chahiye
}Writing a multi-line String (like JSON, HTML, a SQL query) in older Java was messy — a \n at the end of every line, escaping quotes, concatenating with +. Text blocks (starting and ending with """) get rid of all of that.
A text block automatically strips leading whitespace "smartly" (removes the common indentation across all lines), converts line breaks to \n, and you don't need to escape quotes (except in edge cases).
Writing SQL queries, JSON payloads, or HTML templates also becomes easier to review — the reviewer sees the whole structure at once, instead of scattered pieces of string concatenation.
- Common leading whitespace is stripped automatically
- Line breaks are converted to \n automatically
- No need to escape quotes (except in edge cases)
// Purana tareeka:
String json1 = "{\n" +
" \"name\": \"Aarav\",\n" +
" \"age\": 25\n" +
"}";
// Text block (Java 15+):
String json2 = """
{
"name": "Aarav",
"age": 25
}
""";Switch Expressions (Java 14+, stable) are shorter and safer than the old switch statement — they use arrow syntax (case X -> result), there's no fall-through (no need for a break at the end of every case), and they can "return" a value too (usable directly in an assignment).
In Java 17, Pattern Matching for switch arrived as a preview feature (stabilized in later versions) — now you can branch in a switch based on type too, with pattern binding just like instanceof: case Integer i -> ..., case String s -> ....
You can also list multiple case labels together with commas — case 1, 2, 3 -> "Weekday"; — this was already possible in the old switch statement, but reads even cleaner with the arrow syntax.
// Purana switch statement:
int day = 3;
String name;
switch (day) {
case 1: name = "Monday"; break;
case 2: name = "Tuesday"; break;
default: name = "Other";
}
// Switch Expression (Java 14+):
String name2 = switch (day) {
case 1 -> "Monday";
case 2 -> "Tuesday";
default -> "Other";
};
// Pattern Matching for switch (preview, Java 17):
Object obj = 42;
String result = switch (obj) {
case Integer i -> "Integer: " + i;
case String s -> "String: " + s;
default -> "Unknown";
};The old java.util.Random used a single algorithm, and adding new/better random algorithms was hard (everything was hardcoded into the Random class itself). Java 17 introduced the RandomGenerator interface, giving a common API for all random number generators, old and new.
New algorithms arrived too — like Xoshiro256PlusPlus, which offers better statistical quality and performance than the old Random, especially for parallel/multi-threaded use (like SplittableRandom, which can give independent streams to different threads without lock overhead).
Interviews don't usually expect deep detail on this topic — it's enough to know RandomGenerator is a new common interface, and that SecureRandom (for cryptographically strong random numbers) sits outside this hierarchy, used for security-sensitive cases.
RandomGenerator rng = RandomGenerator.of("Xoshiro256PlusPlus");
System.out.println(rng.nextInt(100)); // 0-99 ke beech ek random number
// Streams of random numbers bhi easily ban sakte hain:
rng.ints(5, 1, 10).forEach(System.out::println); // 5 numbers, 1-9 ke beechThe module system (JPMS) arrived in Java 9, but for backward compatibility, internal JDK APIs (like sun.misc.Unsafe) could still be accessed with the --illegal-access flag. Since Java 17, these internals are strongly encapsulated — they're no longer accessible by default, no matter what flag you use (only a few critical ones need explicit --add-opens).
This is less directly relevant to your own application code, but if a library/framework you use relied on internal JDK classes (via reflection), it could break when upgrading to Java 17 — which is why this is a common gotcha in migration guides.
This change specifically affects libraries that used "unsafe" internal APIs to optimize performance (like some older ORM frameworks) — most modern libraries have already migrated, but legacy codebases can still run into this when upgrading.
The Security Manager was an old mechanism that let Java applications run sandboxed (like for browser applets) — restricting what code was allowed to do (file access, network, etc.). Modern applications rarely use it (container/OS-level sandboxing has become much more common), and it was costly for the JDK team to maintain.
In Java 17 it was marked "deprecated for removal" (fully removed in later versions) — if a legacy application uses it, you'll get a warning before it stops working, and you'll eventually need to find an alternative.
Modern deployments instead lean on container-level isolation (Docker), OS-level sandboxing, or cloud-provider IAM policies — infrastructure-level security is generally considered more practical than an application-level security manager these days.