🚀
Java 11

Java 11 Features

var, HTTP Client & New Methods
💡 Java 11 ek "quality of life" update jaisa hai — koi bada naya paradigm nahi laata (Java 8 ki tarah), balki roz ke chhote-chhote kaamon ko aasan bana deta hai. Jaise ek purani gaadi mein naye convenient features add ho jaayein — automatic wipers, better AC — engine wahi hai, lekin drive karna zyada smooth ho jaata hai.

Java 11 (September 2018) ek LTS (Long-Term Support) release hai — matlab isse companies production mein bharose ke saath use karti hain, kyunki Oracle isse lambe samay tak support karta hai (Java 8 ke baad sabse popular LTS version).

Isme kai chhoti lekin useful additions aaye: naye String methods (isBlank, strip, lines, repeat), Files.readString()/writeString() se file I/O aasan hua, ek naya standard HTTP Client API, aur single-file Java programs ko bina compile kiye directly run karne ki facility.

Interview mein Java 11 ke features aksar "Java 8 ke baad kya naya aaya" jaisi follow-up questions mein poochhe jaate hain — especially var in lambdas, naye String methods, aur 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 ek "quality of life" update jaisa hai — koi bada naya paradigm nahi laata (Java 8 ki tarah), balki roz ke chhote-chhote kaamon ko aasan bana deta hai. Jaise ek purani gaadi mein naye convenient features add ho jaayein — automatic wipers, better AC — engine wahi hai, lekin drive karna zyada smooth ho jaata hai.
1 / 6
⚡ Quick Recap
  • Java 11 = LTS release (Sept 2018)
  • var lambda parameters mein use ho sakta hai
  • isBlank/strip/lines/repeat = naye String methods
  • java.net.http = naya standard HTTP Client
  • Single-file .java programs bina compile ke run ho sakte hain
Is page mein (8 subtopics)

Java 10 mein "var" aaya tha local variables ke liye (var x = 10;), lekin lambda parameters mein use nahi kar sakte the. Java 11 ne ye gap fill kiya — ab lambda ke parameters mein bhi var likh sakte ho, jaise (var a, var b) -> a + b.

Iska fayda tab hai jab tumhe parameter par annotation lagana ho (jaise @NotNull var x) — bina var ke, lambda parameters par annotation lagana syntactically possible nahi tha. Sirf naam likhne se (a, b) -> ... aur var likhne se (var a, var b) -> ... same hi compile hota hai — koi performance fark nahi, sirf annotation support ke liye ye feature aaya.

Rule: ya to saare parameters mein var likho, ya kisi mein nahi — mix nahi kar sakte, jaise (var a, b) -> ... galat hai (compile error).

Interview mein pucha ja sakta hai ki var ek "dynamic typing" feature hai kya — nahi, Java abhi bhi statically typed hai, var sirf compiler ko type infer karne deta hai compile-time par hi, runtime par kuch change nahi hota.

  • Bina var: (a, b) -> a + b — chhota, zyadatar cases ke liye kaafi
  • var ke saath: (var a, var b) -> a + b — annotation lagane ke kaam aata hai
  • Mix karna galat: (var a, b) -> ... compile error dega
// 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 karna allowed nahi hai — (var a, b) -> a + b likhoge to compile error aayega. Ya to sab parameters var honge, ya koi nahi.

isBlank() check karta hai String khaali hai ya sirf whitespace hai — isEmpty() sirf length 0 check karta hai, lekin " " (sirf spaces) ke liye isEmpty() false dega, jabki isBlank() true dega. Ye ek common bug source tha Java 11 se pehle.

strip()/stripLeading()/stripTrailing() trim() jaise hi hain, lekin Unicode-aware hain — trim() sirf ASCII whitespace (space se kam ya barabar character code) samajhta hai, jabki strip() Unicode whitespace bhi handle karta hai (jaise non-breaking spaces). Modern code mein trim() ki jagah strip() prefer kiya jaata hai.

lines() String ko line-by-line ek Stream<String> mein todta hai (multi-line text ke liye useful, bina manually split("\n") kiye). repeat(n) ek String ko n baar repeat karke ek naya String banata hai.

Real-world use-case: form input validation mein isBlank() se turant check kar sakte ho ki user ne kuch meaningful type kiya ya sirf spaces daal diye — pehle ye manual trim().isEmpty() se karna padta tha.

  • isBlank() — sirf whitespace hai kya, check karta hai
  • strip()/stripLeading()/stripTrailing() — Unicode-aware trim
  • lines() — String ko line-by-line Stream mein todta hai
  • repeat(n) — String ko n baar repeat karta hai
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() aur isBlank() dono use karne se pehle soch lo kya chahiye — form validation mein (jaha user sirf spaces type kar de) isBlank() zyada sahi check hai.

Java 11 se pehle poori file ek String mein padhne ke liye Files.readAllBytes() call karke manually new String(bytes, charset) karna padta tha, ya Files.lines() se stream collect karna padta tha — thoda boilerplate. Files.readString(path) ye sab ek line mein kar deta hai.

Files.writeString(path, content) similarly ek String ko seedha file mein likh deta hai, bina manually bytes convert kiye. Dono methods UTF-8 default use karte hain (overload mein custom Charset bhi de sakte ho).

Chhote config files, templates, ya test fixtures padhne/likhne ke liye ye methods perfect hain — bade data files ya log processing ke liye NIO ke stream-based APIs (jaise Files.lines()) zyada suitable rehte hain.

// 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() poori file memory mein load karta hai — bahut badi files (GBs) ke liye risky hai, bade files ke liye BufferedReader se line-by-line hi padho.

Java 9 mein incubator (experimental) module ke roop mein aaya tha, Java 11 mein ye standard java.net.http package ban gaya — purane HttpURLConnection (jo Java 1.1 se tha, clunky aur limited) ka modern replacement.

Naya client HTTP/2 support karta hai (default), synchronous (send()) aur asynchronous (sendAsync(), jo CompletableFuture return karta hai) dono tareeke deta hai, aur fluent Builder pattern use karta hai request banane ke liye — third-party libraries (jaise Apache HttpClient ya OkHttp) ki zaroorat kam ho jaati hai simple use-cases ke liye.

Microservices architecture mein jaha ek service doosri service ko REST call karti hai, ye built-in client third-party dependency add kiye bina kaam chala deta hai — chhote projects ke liye especially useful, jaha ek poori library add karna overkill lagta hai.

  • HTTP/2 support by default
  • send() — synchronous, jawaab aane tak wait karta hai
  • sendAsync() — asynchronous, CompletableFuture return karta hai
  • Fluent Builder pattern se request banana
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 karo jab multiple requests parallel mein bhejni ho, ya UI thread ko block nahi karna ho — ye CompletableFuture<HttpResponse<String>> return karta hai jise thenApply()/thenAccept() se chain kar sakte ho.

Normally Java mein pehle javac se compile karke .class file banani padti thi, fir java se run karte the. Java 11 se ek single .java file ko directly java command se run kar sakte ho, bina explicit compile step ke — java Hello.java. JVM khud background mein compile karke memory mein hi run kar deta hai (koi .class file disk par nahi banti).

Ye feature sirf single-file programs ke liye hai (multi-file projects ke liye nahi) — quick scripts, prototyping, ya seekhne ke liye bahut useful hai, kyunki do commands (javac + java) ki jagah ek hi command chalti hai.

Ye feature especially coding interviews aur competitive programming ke liye handy hai — kisi bhi online judge ya quick script ke liye bina project setup kiye seedha code likh kar chala sakte ho.

// 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: Ye feature production deployment ke liye nahi hai — real projects mein Maven/Gradle se proper build hi use hota hai. Ye sirf quick testing/learning ke liye convenient hai.

Collection.toArray(IntFunction<T[]> generator) ek naya overload hai — pehle toArray(new String[0]) jaisa likhna padta tha, ab toArray(String[]::new) jaisa cleaner method reference use kar sakte ho, jisme array size khud collection decide kar leta hai.

Optional.isEmpty() add hua — pehle sirf isPresent() tha, aur "agar value nahi hai" check karne ke liye !optional.isPresent() likhna padta tha. isEmpty() zyada readable hai (negation avoid hota hai).

toArray(String[]::new) purane toArray(new String[0]) se better hai kyunki JIT compiler is pattern ko intrinsify kar sakta hai, jisse bade collections par thoda better performance bhi milta hai — ek chhoti si syntax change ka real benefit.

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");
}

Kabhi-kabhi ek existing Predicate (jaise String::isBlank) ko negate karna hota hai — method reference ko directly negate nahi kar sakte (String::isBlank ka negate() call nahi ho sakta seedhe), isliye pehle lambda likhna padta tha: s -> !s.isBlank().

Predicate.not(predicate) ek static helper hai jo isko clean bana deta hai — Predicate.not(String::isBlank) seedha method reference ko negate kar deta hai, bina extra lambda likhe.

Static import (import static java.util.function.Predicate.not;) ke saath aur bhi clean ho jaata hai — sirf not(String::isBlank) likh sakte ho, poora "Predicate." prefix bhi hata sakte ho.

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) ek "no-op" (kuch nahi karne wala) garbage collector hai — ye memory allocate to karta hai, lekin kabhi collect nahi karta. Sunne mein ajeeb lagta hai, lekin performance testing (GC ka overhead measure karna) ya bahut short-lived programs (jo khatam hone se pehle memory khatam hi nahi karenge) ke liye useful hai.

ZGC (JEP 333, is version mein experimental) ek scalable, low-latency garbage collector hai jo GB se lekar multi-TB heaps tak handle kar sakta hai, pause times ko 10ms se kam rakhte hue — bahut bade applications (jaha thoda sa bhi pause noticeable ho) ke liye design kiya gaya tha. Interview mein in dono ka naam aur ek-line purpose yaad rakhna kaafi hota hai — deep internals shayad hi poochhe jaate hain.

Interview mein agar poocha jaaye "production mein Epsilon GC kab use karoge" — jawaab hai: shayad kabhi nahi, ye sirf testing/benchmarking tool hai. Production ke liye G1 (default) ya specific latency needs ke liye ZGC zyada practical choices hain.

GCPurpose
EpsilonNo-op — sirf allocate karta hai, collect kabhi nahi (testing/measurement ke liye)
ZGCBade heaps, bahut kam pause time (experimental in Java 11)
G1 (Java 9+ default)General-purpose, balanced throughput + pause time