Java 17 Features
Java 17 (September 2021) दूसरी major LTS (Long-Term Support) release है Java 11 के बाद — बहुत companies इसी version पर migrate करती हैं क्योंकि इसमें कई साल के improvements एक साथ आते हैं (Java 12 से 17 तक के सारे features)।
सबसे बड़े highlights: Records (data classes एक line में), Sealed Classes (controlled inheritance), Pattern Matching for instanceof (auto-casting), Text Blocks (multi-line strings आसानी से), और Switch Expressions।
Interview में Java 17 के features बहुत common हैं, especially Records और Sealed Classes — क्योंकि ये modern Java code लिखने का तरीका बदल देते हैं, 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
}Normal class में एक simple data-holder (जैसे Point जिसमें सिर्फ x और y हों) बनाने के लिए काफी boilerplate लिखना पड़ता है — constructor, getters, equals(), hashCode(), toString() सब manually (या IDE से generate करके)। record keyword यह सब automatically generate कर देता है एक line में।
record Point(int x, int y) {} लिखने से compiler खुद बनाता है: एक constructor (दोनों fields set करने वाला), getter methods (x() और y() — बिना "get" prefix के), और properly implemented equals(), hashCode(), toString()। Records implicitly final हैं (extend नहीं हो सकते) और उनके fields भी implicitly final हैं (immutable)।
Records तब best हैं जब तुम्हें सिर्फ data carry करना हो, कोई complex behavior नहीं — जैसे API responses, DTOs (Data Transfer Objects), या coordinate pairs। अगर class में methods/logic भी चाहिए (सिर्फ data नहीं), normal class ही better रहेगी।
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)Normal class/interface को कोई भी extend/implement कर सकता है — sealed keyword से तुम control करते हो *exactly* कौन-कौन extend/implement कर सकता है। यह especially useful है जब तुम्हें पता हो कि सब possible subtypes क्या हैं (जैसे Shape सिर्फ Circle, Square, Triangle हो सकता है, और कुछ नहीं)।
sealed class Shape permits Circle, Square, Triangle {} लिखने से सिर्फ ये तीन classes ही Shape extend कर सकती हैं — कोई बाहर का code नया subtype नहीं बना सकता। हर permitted subclass को explicitly declare करना पड़ता है: final (आगे extend नहीं हो सकती), sealed (खुद आगे control करती है), या non-sealed (वापस normal, कुछ भी extend कर सकता है)।
फ़ायदा: switch statements में compiler को पता होता है सारे possible types क्या हैं, इसलिए "exhaustiveness checking" possible होता है (अगला subtopic में pattern matching के साथ देखेंगे) — बिना default case के भी compiler confirm कर सकता है सारे cases cover हो गए।
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 degaपुराने Java में instanceof check करने के बाद manually cast करना पड़ता था — दो steps, थोड़ा repetitive: if (obj instanceof String) { String s = (String) obj; ... }। Java 16+ (17 में stable) में instanceof खुद एक variable "bind" कर देता है अगर check pass हो जाए।
if (obj instanceof String s) लिखने से, अगर obj String है, तो s automatically उस cast-किए-हुए value को point करता है — उस if block के अंदर सीधा s use कर सकते हो, manual cast की ज़रूरत नहीं। यह code को छोटा और safer बनाता है (ClassCastException का risk कम होता है क्योंकि compiler खुद type-check करता है)।
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
}Multi-line String (जैसे JSON, HTML, SQL query) लिखना पुराने Java में बहुत messy था — हर line के end में \n, quotes escape करना, + से concatenate करना। Text block (""" से शुरू और खत्म होके) इस सब को खत्म कर देता है।
Text block automatically leading whitespace को "smart" तरीके से strip करता है (सारी lines का common indentation हटा देता है), line breaks को \n में convert कर देता है, और quotes को escape करने की ज़रूरत नहीं (सिर्फ edge cases में)।
// Purana tareeka:
String json1 = "{\n" +
" \"name\": \"Aarav\",\n" +
" \"age\": 25\n" +
"}";
// Text block (Java 15+):
String json2 = """
{
"name": "Aarav",
"age": 25
}
""";Switch Expression (Java 14+, stable) पुराने switch statement से छोटा और safer है — arrow syntax (case X -> result) use करता है, fall-through नहीं होता (हर case के end में break नहीं चाहिए), और एक value "return" भी कर सकता है (assignment में directly use करने लायक)।
Java 17 में Pattern Matching for switch preview feature के रूप में आया (बाद की versions में stable हुआ) — अब switch में type के basis पर भी branch कर सकते हो, instanceof जैसा ही pattern binding के साथ: case Integer i -> ..., case String s -> ...।
// 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";
};पुराना java.util.Random एक ही algorithm use करता था, और नए/बेहतर random algorithms add करना मुश्किल था (सब कुछ Random class में ही hardcoded था)। Java 17 ने RandomGenerator interface दिया जो सारे random number generators (नए पुराने) के लिए एक common API देता है।
नए algorithms भी आए — जैसे Xoshiro256PlusPlus, जो पुराने Random से better statistical quality और performance देते हैं, especially parallel/multi-threaded use के लिए (जैसे SplittableRandom जो अलग-अलग threads को independent streams दे सकता है बिना lock overhead के)।
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 beechJava 9 में module system (JPMS) आया था, लेकिन backward compatibility के लिए internal JDK APIs (जैसे sun.misc.Unsafe) तब भी --illegal-access flag से access हो सकते थे। Java 17 से ये internals strongly encapsulate हो गए — by default access नहीं हो सकते, चाहे कुछ भी flag use करो (सिर्फ critical ones के लिए --add-opens explicitly देना पड़ता है)।
यह application code के लिए directly कम relevant है, लेकिन अगर तुम्हारी कोई library/framework internal JDK classes use करती थी (reflection से), Java 17 upgrade करते वक्त यह break हो सकता है — इसीलिए migration guides में यह एक common gotcha है।
Security Manager एक पुराना mechanism था जो Java applications को sandbox में चलाने देता था (जैसे browser applets के लिए) — restrict करता था कि code क्या कर सकता है (file access, network, etc.)। Modern applications इसको rarely use करते हैं (containers/OS-level sandboxing ज़्यादा common हो गया है), और maintain करना JDK team के लिए costly था।
Java 17 में इसे "deprecated for removal" mark किया गया (बाद की versions में completely remove हो गया) — अगर कोई legacy application इसको use करती है, upgrade से पहले warning आएगी, और eventually alternative ढूंढना पड़ेगा।