Java 11 Features
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 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).
// 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;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.
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"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).
// 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!");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.
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());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.
// 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!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).
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.
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 (clean) 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.
| GC | Purpose |
|---|---|
| Epsilon | No-op — sirf allocate karta hai, collect kabhi nahi (testing/measurement ke liye) |
| ZGC | Bade heaps, bahut kam pause time (experimental in Java 11) |
| G1 (Java 9+ default) | General-purpose, balanced throughput + pause time |