Java Evolution: Java 8 से Java 24 तक क्या बदला और क्यों यह महत्वपूर्ण है
Java के version 8 से 24 तक के विकास के लिए एक व्यापक guide — lambdas, streams, records, sealed classes, virtual threads, pattern matching, और हर उस प्रमुख feature को cover करता है जिसने Java लिखने के तरीके को बदला।
Verbose से Elegant तक: Java का एक दशक
Java 8 ने 2014 में lambdas और streams के साथ नियम फिर से लिखे। तब से, हर छह महीने में एक नया version ship होता है। ज़्यादातर developers Java 8 से 11 पर गए, फिर 17, अब 21। यहाँ सब कुछ है जो बदला — version by version — उन features के साथ जिनका आप वास्तव में इस्तेमाल करेंगे।
Java 8 (2014) — LTS — Modern Java का Big Bang
Java 8 ने Java में functional programming की शुरुआत की। यह वह version है जिसे ज़्यादातर developers गहराई से जानते हैं।
Lambda Expressions और Functional Interfaces
Anonymous inner classes को concise syntax से बदल दिया। Core interfaces: Predicate<T>, Function<T,R>, Consumer<T>, Supplier<T>।
// Lambda + Predicate composition
Predicate<Product> inStock = p -> p.getQuantity() > 0;
Predicate<Product> isExpensive = p -> p.getPrice() > 100.0;
List<Product> premiumAvailable = products.stream()
.filter(inStock.and(isExpensive))
.collect(Collectors.toList());
// All 4 core functional interfaces
Predicate<Employee> isSenior = e -> e.getYears() > 5; // T -> boolean
Function<Employee, String> fullName = e -> e.getFirstName() + " " + e.getLastName(); // T -> R
Consumer<Employee> sendWelcome = e -> emailService.send(e); // T -> void
Supplier<Employee> defaultEmp = () -> new Employee("Guest"); // () -> T
Stream API
Lazy evaluation के साथ declarative data processing। मुख्य operations: filter, map, flatMap, collect, reduce, groupingBy।
// Filter + Map + Collect
List<String> activeNames = employees.stream()
.filter(e -> e.getStatus() == Status.ACTIVE)
.map(Employee::getName)
.sorted()
.collect(Collectors.toList());
// GroupingBy + downstream counting
Map<Department, Long> headcount = employees.stream()
.collect(Collectors.groupingBy(Employee::getDepartment, Collectors.counting()));
// FlatMap — flatten nested collections
List<String> allTags = articles.stream()
.flatMap(a -> a.getTags().stream())
.distinct()
.collect(Collectors.toList());
// PartitioningBy — split into true/false groups
Map<Boolean, List<Order>> shipped = orders.stream()
.collect(Collectors.partitioningBy(Order::isShipped));
Optional
Nullable values के लिए container। केवल return types के लिए इस्तेमाल करें, कभी भी fields या parameters के लिए नहीं।
// Safe navigation through nested nullables
String cityName = Optional.ofNullable(customer)
.map(Customer::getAddress)
.map(Address::getCity)
.orElse("UNKNOWN");
// orElseGet is lazy — supplier only runs if empty
Product fallback = products.stream()
.filter(Product::isAvailable)
.findFirst()
.orElseGet(() -> new Product("Default", 0.0));
CompletableFuture
Composition के साथ non-blocking async operations।
CompletableFuture<Double> priceCheck = CompletableFuture.supplyAsync(() -> fetchPrice(sku));
CompletableFuture<Integer> stockCheck = CompletableFuture.supplyAsync(() -> fetchStock(sku));
// Combine two async results
CompletableFuture<String> summary = priceCheck
.thenCombine(stockCheck, (price, stock) ->
"Price: $" + price + ", Stock: " + stock)
.exceptionally(ex -> "Error: " + ex.getMessage()); // fallback on error
java.time API और Default Methods
Immutable, thread-safe date/time classes: LocalDate, LocalDateTime, ZonedDateTime, Instant, Duration। Backward-compatible evolution के लिए interfaces ने default methods प्राप्त किए।
Java 9 (2017) — Modules और Collection Factories
Immutable Collection Factories
List<String> colors = List.of("red", "green", "blue"); // immutable
Set<Integer> primes = Set.of(2, 3, 5, 7, 11); // immutable
Map<String, Integer> scores = Map.of("Alice", 95, "Bob", 87); // immutable
Optional और Stream Enhancements
// Optional: ifPresentOrElse, or(), stream()
opt.ifPresentOrElse(v -> process(v), () -> logMissing());
Optional<String> result = opt.or(() -> Optional.of("default"));
// Stream: takeWhile, dropWhile
List<Integer> prefix = Stream.of(1, 2, 3, 10, 4)
.takeWhile(x -> x < 5) // [1, 2, 3] — stops at first false
.toList();
Private Interface Methods
Default methods में कोड पुनः उपयोग के लिए interfaces में helper methods।
Java 10 (2018) — var Keyword
// Local variable type inference
var products = new ArrayList<Product>(); // inferred as ArrayList<Product>
var stream = products.stream(); // inferred as Stream<Product>
// Works in for loops
for (var product : products) {
System.out.println(product.getName());
}
// Unmodifiable copies
var snapshot = List.copyOf(mutableList); // immutable copy
सीमाएँ: var केवल local variables के लिए काम करता है — fields, method parameters, या return types के लिए नहीं। null के साथ initialize नहीं किया जा सकता।
Java 11 (2018) — LTS — Java 8 के बाद पहला LTS
// String enhancements
" hello ".isBlank(); // false
" hello ".strip(); // "hello" (Unicode-aware trim)
"line1
line2".lines(); // Stream<String>
"ha".repeat(3); // "hahaha"
// Optional.isEmpty() — opposite of isPresent()
Optional.empty().isEmpty(); // true
// var in lambda parameters (useful for adding annotations)
list.stream()
.map((@NonNull var s) -> s.toUpperCase())
.toList();
// Predicate.not() — cleaner negation
list.stream().filter(Predicate.not(String::isBlank)).toList();
Java 12–13 (2019) — Switch Expressions और Text Blocks
// Switch expressions — arrow syntax, no fall-through, yields values
String label = switch (priority) {
case HIGH, CRITICAL -> "URGENT";
case MEDIUM -> "REVIEW";
case LOW -> "BACKLOG";
};
// Text blocks — multi-line strings
String query = """
SELECT id, name, department
FROM employees
WHERE status = 'ACTIVE'
ORDER BY hire_date
""";
// String.indent() and String.transform()
String result = input.transform(String::strip)
.transform(String::toUpperCase);
Java 14 (2020) — Records और Pattern Matching
Records — Immutable Data Classes
Constructor, accessors, equals(), hashCode(), toString() auto-generate होते हैं।
// One line replaces 50+ lines of boilerplate
public record OrderSummary(String orderId, String customerName,
double total, Status status) {}
// Compact constructor for validation
public record Price(double value, String currency) {
public Price {
if (value < 0) throw new IllegalArgumentException("Negative price");
currency = currency.toUpperCase();
}
}
instanceof के लिए Pattern Matching
// Before: cast manually
if (obj instanceof String) {
String s = (String) obj;
System.out.println(s.length());
}
// After: binding variable in one step
if (obj instanceof String s && s.length() > 5) {
System.out.println(s.toUpperCase());
}
Java 15 (2020) — Sealed Classes Preview और ZGC Production
Text blocks finalize हुए। ZGC garbage collector production-ready हो गया। Sealed classes preview में पेश किए गए। Nashorn JavaScript engine हटाया गया।
// ZGC — now production-ready, no experimental flag needed
// java -XX:+UseZGC MyApp
// Hidden classes — used internally by frameworks like Spring/Hibernate
// for runtime-generated proxy classes
Java 16 (2021) — Stream.toList() और Records Finalized
// Stream.toList() — cleaner than Collectors.toList()
List<String> names = employees.stream()
.map(Employee::getName)
.toList(); // returns unmodifiable list
// mapMulti — alternative to flatMap for conditional one-to-many
Stream.of(1, 2, 3, 4).<String>mapMulti((num, consumer) -> {
if (num % 2 == 0) {
consumer.accept(num + " is even");
consumer.accept(num + " doubled = " + (num * 2));
}
}).toList();
Java 17 (2021) — LTS — Sealed Classes और Pattern Switch
वर्तमान enterprise standard। Sealed classes और pattern matching for switch finalize हुए।
Sealed Classes — Controlled Inheritance
public sealed interface PaymentResult
permits Success, Failure, Pending {
}
public record Success(String txnId, double amount) implements PaymentResult {}
public record Failure(String error, int code) implements PaymentResult {}
public record Pending(String txnId) implements PaymentResult {}
// Exhaustive switch — compiler ensures all cases covered
String describe(PaymentResult result) {
return switch (result) {
case Success s -> "Paid $" + s.amount();
case Failure f -> "Failed: " + f.error();
case Pending p -> "Pending: " + p.txnId();
};
}
Algebraic Data Types (ADTs)
Sealed interface + records = functional programming से sum types। Compiler exhaustiveness की गारंटी देता है — कोई default case ज़रूरी नहीं।
Java 18 (2022) — UTF-8 Default और Simple Web Server
// UTF-8 is now the default charset on ALL platforms
// No more "works on my machine" charset bugs
System.out.println(Charset.defaultCharset()); // "UTF-8" everywhere
// Built-in simple web server for testing/prototyping
// Command line: jwebserver -p 9000 -d /path/to/files
var server = SimpleFileServer.createFileServer(
new InetSocketAddress(8080),
Path.of("/www"),
OutputLevel.INFO
);
server.start();
// @snippet in Javadoc replaces <pre>{@code ...}</pre>
Java 19 (2022) — Virtual Threads और Structured Concurrency Preview
Project Loom का पहला preview — Java 5 के बाद concurrency में सबसे बड़ा बदलाव।
// Virtual threads: lightweight (~KB vs ~MB for platform threads)
Thread.ofVirtual().start(() -> {
System.out.println("Running in virtual thread");
});
// Handle 100,000 concurrent tasks — impossible with platform threads
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 100_000).forEach(i ->
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
})
);
}
// Structured concurrency — fan-out pattern
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Subtask<User> user = scope.fork(() -> fetchUser());
Subtask<Account> acct = scope.fork(() -> fetchAccount());
scope.join().throwIfFailed();
return new Profile(user.get(), acct.get());
}
Java 20 (2023) — Refinement Release
सभी 7 JEPs previews/incubators हैं। मुख्य addition: Scoped Values — virtual threads के लिए design किया गया ThreadLocal का एक lightweight, immutable replacement।
// ScopedValue — replaces ThreadLocal for virtual threads
static final ScopedValue<String> CURRENT_USER = ScopedValue.newInstance();
void handleRequest(String username) {
ScopedValue.runWhere(CURRENT_USER, username, () -> {
processRequest(); // all called methods can read CURRENT_USER.get()
});
}
// Why better? Immutable, auto-inherited by child virtual threads, bounded lifetime
Java 21 (2023) — LTS — Virtual Threads, Record Patterns, Sequenced Collections
नवीनतम LTS। Virtual threads, pattern matching for switch, और record patterns सभी finalize हुए।
Virtual Threads (Finalized)
// M:N scheduling — millions of virtual threads on few OS threads
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < 1_000_000; i++) {
executor.submit(() -> {
// Each task gets its own virtual thread
return callExternalService();
});
}
}
Record Patterns — Destructuring
record Point(int x, int y) {}
record Line(Point start, Point end) {}
// Nested destructuring in switch
String describe(Object obj) {
return switch (obj) {
case Line(Point(var x1, var y1), Point(var x2, var y2))
-> "Line from (%d,%d) to (%d,%d)".formatted(x1, y1, x2, y2);
case Point(var x, var y) -> "Point at (%d,%d)".formatted(x, y);
default -> "Unknown";
};
}
Sequenced Collections
// New methods on ordered collections
List<String> list = List.of("a", "b", "c");
list.getFirst(); // "a"
list.getLast(); // "c"
list.reversed(); // ["c", "b", "a"]
// Also works on LinkedHashSet, LinkedHashMap, Deque
Java 22 (2024) — Unnamed Variables और FFM API
Unnamed Variables (_)
// Intentionally unused variable — no more "unused variable" warnings
try (var _ = ScopedContext.acquire()) { /* don't need the ref */ }
for (var _ : collection) { count++; }
map.forEach((_, value) -> process(value));
try { riskyOp(); } catch (Exception _) { log("failed"); }
// In pattern matching
if (obj instanceof Point(var x, _)) { /* only care about x */ }
Stream Gatherers (Preview)
// Sliding window
List<List<Integer>> windows = Stream.of(1, 2, 3, 4, 5)
.gather(Gatherers.windowSliding(3)).toList();
// [[1,2,3], [2,3,4], [3,4,5]]
// Fixed-size batches
List<List<Integer>> batches = Stream.of(1,2,3,4,5,6,7)
.gather(Gatherers.windowFixed(3)).toList();
// [[1,2,3], [4,5,6], [7]]
Foreign Function और Memory API (Finalized)
JNI का safe replacement। memory safety की गारंटी के साथ Java से सीधे native C functions call करें।
Java 23 (2024) — Markdown Javadoc और ZGC Default
Patterns में Primitive Types (Preview)
String describe(int statusCode) {
return switch (statusCode) {
case 200 -> "OK";
case 404 -> "Not Found";
case int i when i >= 500 -> "Server Error: " + i;
case int i -> "Other: " + i;
};
}
Markdown Documentation Comments
/// Returns the **full name** of the user.
///
/// This method combines:
/// - First name
/// - Last name
///
/// @param user the user object
/// @return the concatenated full name
public String getFullName(User user) { ... }
Module Import Declarations (Preview)
// One import for an entire module
import module java.base; // imports java.util, java.io, java.nio, etc.
Note: String Templates (21–22 में previewed) design issues के कारण Java 23 में वापस ले लिए गए।
Java 24 (2025) — Stream Gatherers Finalized, AOT, Virtual Thread Unpinning
24 JEPs के साथ अब तक की सबसे बड़ी release।
Stream Gatherers (Finalized)
// Built-in: windowFixed, windowSliding, fold, scan, mapConcurrent
List<Response> responses = urls.stream()
.gather(Gatherers.mapConcurrent(5, this::httpGet))
.toList();
// Custom gatherer: distinct by key
static <T, K> Gatherer<T, ?, T> distinctBy(Function<T, K> keyExtractor) {
return Gatherer.ofSequential(HashSet::new,
(seen, element, downstream) -> {
if (seen.add(keyExtractor.apply(element)))
return downstream.push(element);
return true;
});
}
// Usage: people.stream().gather(distinctBy(Person::lastName)).toList();
Ahead-of-Time Class Loading (Project Leyden)
# Record → Build cache → Launch with up to 42% faster startup
java -XX:AOTMode=record -XX:AOTConfiguration=app.aotconf -cp app.jar Main
java -XX:AOTMode=create -XX:AOTConfiguration=app.aotconf -XX:AOTCache=app.aot -cp app.jar
java -XX:AOTCache=app.aot -cp app.jar Main
Virtual Thread Unpinning
Virtual threads अब synchronized blocks में carrier threads से pinned नहीं होते। यह Java 21–23 में virtual threads की सबसे बड़ी सीमा थी।
// Java 21–23: synchronized + blocking I/O PINNED the carrier thread
// Java 24: virtual thread unmounts — carrier is free for other work
synchronized (sharedResource) {
return fetchFromDatabase(); // no longer pins! Major perf improvement
}
Class-File API (Finalized)
.class files को parse और generate करने के लिए standard API। ASM जैसी third-party libraries को बदलता है।
अन्य उल्लेखनीय बदलाव
Security Manager स्थायी रूप से disabled। Compact object headers (experimental, 10–20% heap कमी)। Generational Shenandoah GC (experimental)।
LTS Roadmap और किस Version को target करें
| Version | Year | Type | Headline Feature |
|---|---|---|---|
| Java 8 | 2014 | LTS | Lambdas, Streams, Optional |
| Java 11 | 2018 | LTS | String enhancements, var in lambda, HttpClient |
| Java 17 | 2021 | LTS | Sealed classes, pattern matching, records finalized |
| Java 21 | 2023 | LTS | Virtual threads, record patterns, sequenced collections |
| Java 25 | Sep 2025 | LTS | अगला LTS — structured concurrency, scoped values को finalize करने की उम्मीद |
सिफारिश: नए projects के लिए, Java 21 (वर्तमान LTS) target करें। Java 8 या 11 पर अभी भी मौजूद enterprises के लिए, 21 पर migration की योजना बनाएँ। अगले LTS की ज़रूरत है तो Java 25 (सितंबर 2025) का इंतज़ार करें।
मुख्य सीख
Java 8→11: Functional foundations — lambdas, streams, var, string helpers।
Java 12→17: Boilerplate elimination — records, sealed classes, switch expressions, text blocks, pattern matching।
Java 18→24: Concurrency revolution — virtual threads, structured concurrency, scoped values, stream gatherers, AOT compilation।
Java अब वह verbose भाषा नहीं है जो पहले थी। Modern Java (17+) concise, expressive है, और पहले से कहीं बेहतर प्रदर्शन करता है।