🚀
Java 8+

Java 11 Features

var, HTTP Client & New Methods
💡 Java 11 एक "quality of life" update जैसा है — कोई बड़ा नया paradigm नहीं लाता (Java 8 की तरह), बल्कि रोज़ के छोटे-छोटे कामों को आसान बना देता है। जैसे एक पुरानी गाड़ी में नए convenient features add हो जाएं — automatic wipers, better AC — engine वही है, लेकिन drive करना ज़्यादा smooth हो जाता है।

Java 11 (September 2018) एक LTS (Long-Term Support) release है — मतलब इसे companies production में भरोसे के साथ use करती हैं, क्योंकि Oracle इसे लंबे समय तक support करता है (Java 8 के बाद सबसे popular LTS version)।

इसमें कई छोटी लेकिन useful additions आए: नए String methods (isBlank, strip, lines, repeat), Files.readString()/writeString() से file I/O आसान हुआ, एक नया standard HTTP Client API, और single-file Java programs को बिना compile किए directly run करने की facility।

Interview में Java 11 के features अक्सर "Java 8 के बाद क्या नया आया" जैसी follow-up questions में पूछे जाते हैं — especially var in lambdas, नए String methods, और HTTP Client API।

// Naye String methods
System.out.println("  ".isBlank());        // true
System.out.println("Hi".repeat(3));         // HiHiHi

// Files.readString() — ek line mein file padho
String content = Files.readString(Paths.get("notes.txt"));

// var in lambda parameters
BiFunction<Integer, Integer, Integer> add = (var a, var b) -> a + b;
🚀
Java 11 एक "quality of life" update जैसा है — कोई बड़ा नया paradigm नहीं लाता (Java 8 की तरह), बल्कि रोज़ के छोटे-छोटे कामों को आसान बना देता है। जैसे एक पुरानी गाड़ी में नए convenient features add हो जाएं — automatic wipers, better AC — engine वही है, लेकिन drive करना ज़्यादा smooth हो जाता है।
1 / 6
इस page में (8 subtopics)

Java 10 में "var" आया था local variables के लिए (var x = 10;), लेकिन lambda parameters में use नहीं कर सकते थे। Java 11 ने यह gap fill किया — अब lambda के parameters में भी var लिख सकते हो, जैसे (var a, var b) -> a + b।

इसका फ़ायदा तब है जब तुम्हें parameter पर annotation लगाना हो (जैसे @NotNull var x) — बिना var के, lambda parameters पर annotation लगाना syntactically possible नहीं था। सिर्फ नाम लिखने से (a, b) -> ... और var लिखने से (var a, var b) -> ... same ही compile होता है — कोई performance फर्क नहीं, सिर्फ annotation support के लिए यह feature आया।

Rule: या तो सारे parameters में var लिखो, या किसी में नहीं — mix नहीं कर सकते, जैसे (var a, b) -> ... गलत है (compile error)।

// Normal lambda
BiFunction<Integer, Integer, Integer> add1 = (a, b) -> a + b;

// var ke saath (Java 11+)
BiFunction<Integer, Integer, Integer> add2 = (var a, var b) -> a + b;

// Annotation ke saath — sirf var se hi possible
// (var a, @Deprecated var b) -> a + b;
⚠️Common Mistake: Mix करना allowed नहीं है — (var a, b) -> a + b लिखोगे तो compile error आएगा। या तो सब parameters var होंगे, या कोई नहीं।

isBlank() check करता है String खाली है या सिर्फ whitespace है — isEmpty() सिर्फ length 0 check करता है, लेकिन " " (सिर्फ spaces) के लिए isEmpty() false देगा, जबकि isBlank() true देगा। यह एक common bug source था Java 11 से पहले।

strip()/stripLeading()/stripTrailing() trim() जैसे ही हैं, लेकिन Unicode-aware हैं — trim() सिर्फ ASCII whitespace (space से कम या बराबर character code) समझता है, जबकि strip() Unicode whitespace भी handle करता है (जैसे non-breaking spaces)। Modern code में trim() की जगह strip() prefer किया जाता है।

lines() String को line-by-line एक Stream<String> में तोड़ता है (multi-line text के लिए useful, बिना manually split("\n") किए)। repeat(n) एक String को n बार repeat करके एक नया String बनाता है।

String s = "   ";
System.out.println(s.isEmpty());  // false (length > 0 hai)
System.out.println(s.isBlank());  // true (sirf whitespace hai)

String text = "Line1\nLine2\nLine3";
text.lines().forEach(System.out::println); // 3 lines print

System.out.println("Ab".repeat(3)); // "AbAbAb"
💡Tip: isEmpty() और isBlank() दोनों use करने से पहले सोच लो क्या चाहिए — form validation में (जहाँ user सिर्फ spaces type कर दे) isBlank() ज़्यादा सही check है।

Java 11 से पहले पूरी file एक String में पढ़ने के लिए Files.readAllBytes() call करके manually new String(bytes, charset) करना पड़ता था, या Files.lines() से stream collect करना पड़ता था — थोड़ा boilerplate। Files.readString(path) यह सब एक line में कर देता है।

Files.writeString(path, content) similarly एक String को सीधा file में लिख देता है, बिना manually bytes convert किए। दोनों methods UTF-8 default use करते हैं (overload में custom Charset भी दे सकते हो)।

// Purana tareeka (Java 11 se pehle):
byte[] bytes = Files.readAllBytes(Paths.get("notes.txt"));
String content = new String(bytes, StandardCharsets.UTF_8);

// Java 11+:
String content2 = Files.readString(Paths.get("notes.txt"));
Files.writeString(Paths.get("output.txt"), "Hello Java 11!");
⚠️Common Mistake: Files.readString() पूरी file memory में load करता है — बहुत बड़ी files (GBs) के लिए risky है, बड़ी files के लिए BufferedReader से line-by-line ही पढ़ो।

Java 9 में incubator (experimental) module के रूप में आया था, Java 11 में यह standard java.net.http package बन गया — पुराने HttpURLConnection (जो Java 1.1 से था, clunky और limited) का modern replacement।

नया client HTTP/2 support करता है (default), synchronous (send()) और asynchronous (sendAsync(), जो CompletableFuture return करता है) दोनों तरीके देता है, और fluent Builder pattern use करता है request बनाने के लिए — third-party libraries (जैसे Apache HttpClient या OkHttp) की ज़रूरत कम हो जाती है simple use-cases के लिए।

HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/data"))
    .GET()
    .build();

HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
💡Tip: Async version (sendAsync) use करो जब multiple requests parallel में भेजनी हो, या UI thread को block नहीं करना हो — यह CompletableFuture<HttpResponse<String>> return करता है जिसे thenApply()/thenAccept() से chain कर सकते हो।

Normally Java में पहले javac से compile करके .class file बनानी पड़ती थी, फिर java से run करते थे। Java 11 से एक single .java file को directly java command से run कर सकते हो, बिना explicit compile step के — java Hello.java। JVM खुद background में compile करके memory में ही run कर देता है (कोई .class file disk पर नहीं बनती)।

यह feature सिर्फ single-file programs के लिए है (multi-file projects के लिए नहीं) — quick scripts, prototyping, या सीखने के लिए बहुत useful है, क्योंकि दो commands (javac + java) की जगह एक ही command चलती है।

// Hello.java
public class Hello {
  public static void main(String[] args) {
    System.out.println("Direct run, no compile step!");
  }
}

// Terminal mein:
// $ java Hello.java
// Direct run, no compile step!
💡Tip: यह feature production deployment के लिए नहीं है — real projects में Maven/Gradle से proper build ही use होता है। यह सिर्फ quick testing/learning के लिए convenient है।

Collection.toArray(IntFunction<T[]> generator) एक नया overload है — पहले toArray(new String[0]) जैसा लिखना पड़ता था, अब toArray(String[]::new) जैसा cleaner method reference use कर सकते हो, जिसमें array size खुद collection decide कर लेता है।

Optional.isEmpty() add हुआ — पहले सिर्फ isPresent() था, और "अगर value नहीं है" check करने के लिए !optional.isPresent() लिखना पड़ता था। isEmpty() ज़्यादा readable है (negation avoid होता है)।

List<String> names = List.of("Riya", "Aman");
String[] arr = names.toArray(String[]::new); // naya, cleaner tareeka

Optional<String> opt = Optional.empty();
if (opt.isEmpty()) {
  System.out.println("Koi value nahi hai");
}

कभी-कभी एक existing Predicate (जैसे String::isBlank) को negate करना होता है — method reference को directly negate नहीं कर सकते (String::isBlank का negate() call नहीं हो सकता सीधे), इसलिए पहले lambda लिखना पड़ता था: s -> !s.isBlank()।

Predicate.not(predicate) एक static helper है जो इसको clean बना देता है — Predicate.not(String::isBlank) सीधा method reference को negate कर देता है, बिना extra lambda लिखे।

List<String> words = List.of("Java", "", "  ", "Code");

// Java 11 se pehle:
words.stream().filter(s -> !s.isBlank()).forEach(System.out::println);

// Java 11+, Predicate.not() ke saath:
words.stream().filter(Predicate.not(String::isBlank)).forEach(System.out::println);

Epsilon GC (JEP 318) एक "no-op" (कुछ नहीं करने वाला) garbage collector है — यह memory allocate तो करता है, लेकिन कभी collect (clean) नहीं करता। सुनने में अजीब लगता है, लेकिन performance testing (GC का overhead measure करना) या बहुत short-lived programs (जो खत्म होने से पहले memory खत्म ही नहीं करेंगे) के लिए useful है।

ZGC (JEP 333, इस version में experimental) एक scalable, low-latency garbage collector है जो GB से लेकर multi-TB heaps तक handle कर सकता है, pause times को 10ms से कम रखते हुए — बहुत बड़ी applications (जहाँ थोड़ा सा भी pause noticeable हो) के लिए design किया गया था। Interview में इन दोनों का नाम और एक-line purpose याद रखना काफी होता है — deep internals शायद ही पूछे जाते हैं।

GCPurpose
EpsilonNo-op — सिर्फ allocate करता है, collect कभी नहीं (testing/measurement के लिए)
ZGCबड़े heaps, बहुत कम pause time (experimental in Java 11)
G1 (Java 9+ default)General-purpose, balanced throughput + pause time