JAVA 11 Features Interview Q & A
- List out some important features of Java 11
- What is the var keyword in Java 11 ?
- List new String methods in Java 11
- Explain String::repeat with example
- What is the new HTTP Client in Java 11 ?
- How to make synchronous HTTP GET request ?
- How to make asynchronous HTTP GET ?
- What is the use of Files.readString and Files.writeString in Java 11 ?
- What is Collection.toArray(IntFunction) in Java 11 ?
- What is Predicate.not() in Java 11 ?
List out some important features of Java 11
- var keyword - ie local variable type inference
- new String methods (isBlank, lines(), strip(), stripLeading(), stripTrailing(), repeat())
- new HTTP Client (java.net.http.HttpClient) - This is superior than old one HttpURLConnection
- Files.readString and Files.writeString
- Collections.toArray(IntFunction)
- Predicate.not()
What is the var keyword in Java 11 ?
=> var is local variable type inference. i.e compiler infers type from initializer.
=> Example : var list = new ArrayList<String>();
Here, the list is ArrayList<String>. This is how the compiler infers the type.
=> Benefits : Reduces boiler plate code for long generic types
=> Limitations : var is only for local variables (not fields, parameters, return types), must have initializer, Cannot be var x = null;
=> Best practice : Use for readability, avoid when type clarity is important
List new String methods in Java 11
Java 11 added some useful instance methods to the String class. These methods are
- isBlank()
- lines()
- strip(), stripLeading(), stripTrailing()
- repeat(int count)
isBlank() :
=> Returns true if the string is empty or contains only whitespace characters (spaces, tabs, line breaks, etc)
=> Signature : public boolean isBlank()
=> It replaces the common pattern str.trim().isEmpty()
=> isEmpty() vs isBlank() :
isEmpty() only checks length == 0.
" ".isEmpty() is false (length = 3).
" ".isBlank() is true.
Use isBlank() (Java 11+) for whitespace-aware check
or trim().isEmpty() for older Java
lines() :
=> Returns a Stream<String> ie Lines extracted from the String, separated by line terminators (\n, \r, \r\n)
=> Signature : public Stream<String> lines()
=> Why useful : Makes it easy to process multi-line strings line by line using Stream API
=> Example :
String multiLine = "Line 1\nLine 2\r\nLine 3\rLine 4";
multiLine.lines()
.forEach(System.out::println);
// Output:
// Line 1
// Line 2
// Line 3
// Line 4
multiLine.lines()
.forEach(System.out::println);
// Output:
// Line 1
// Line 2
// Line 3
// Line 4
=> Example (Couting the non blank lines from the given String)
long nonBlankLines = multiLine.lines()
.filter(s -> !s.isBlank())
.count();
.filter(s -> !s.isBlank())
.count();
strip(), stripLeading(), stripTrailing() :
=> These are unicode-aware versions of trim()
=> strip(): Removes leading and trailing whitespace (including Unicode whitespace like non-breaking space \u00A0).
=> stripLeading(): Removes only leading whitespace.
=> stripTrailing(): Removes only trailing whitespace.
=> trim() vs strip() :
trim() only removes characters ≤ U+0020 (basic ASCII space).
strip() removes all Unicode whitespace characters.
=> Example :
String s = "\u2000 Hello \u2000"; // Unicode spaces
s.trim() // "\u2000 Hello \u2000" (trim doesn't remove \u2000)
s.strip() // "Hello" (strip removes \u2000)
s.trim() // "\u2000 Hello \u2000" (trim doesn't remove \u2000)
s.strip() // "Hello" (strip removes \u2000)
=> Practical use : Internationalized applications (text with non-ASCII whitespace).
repeat(int count) :
=> Returns a string that is this string repeated count times
=> Signature : public String repeat(int count)
=> Note : Throws IllegalArgumentException if count < 0
=> Example :
"Hello".repeat(3) // "HelloHelloHello"
"-".repeat(10) // "----------"
"".repeat(5) // ""
"Hi".repeat(0) // ""
// "Hi".repeat(-1) // throws IllegalArgumentException
"-".repeat(10) // "----------"
"".repeat(5) // ""
"Hi".repeat(0) // ""
// "Hi".repeat(-1) // throws IllegalArgumentException
=> Practical use :
Padding, separators, formatting
Example: "-".repeat(20) for a divider line
Explain String::repeat with example
=> Repeats the string n times
=> Example: "Hi".repeat(3) → "HiHiHi"
=> Useful for padding, formatting
What is the new HTTP Client in Java 11 ?
=> Java 11 introduced new standardized HTTP client i.e java.net.http.HttpClient
=> It replaces the old HttpURLConnection
=> This new HTTP client supports
both HTTP/1.1 and HTTP/2,
both Synchronous and Asynchronous requests
=> This new HTTP client provides built-in websocket support
Issue with Old HttpURLConnection | How New HttpClient Fixes It |
|---|---|
| Blocking only (no async) | Supports both sync and async |
| No HTTP/2 support | Full HTTP/2 with upgrade |
| Verbose and error-prone API | Fluent, builder pattern |
| Poor error handling | Better exception hierarchy |
| No WebSocket support | Built-in WebSocket client |
| Not thread-safe | Immutable and thread-safe |
=> Code Examples
Synchronous GET request :
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class HttpClientExample {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Body: " + response.body());
}
}
Asynchronous GET request :
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join(); // Wait for completion (or handle in background)
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join(); // Wait for completion (or handle in background)
WebSocket Example :
HttpClient client = HttpClient.newHttpClient();
WebSocket ws = client.newWebSocketBuilder()
.buildAsync(URI.create("wss://echo.websocket.org"), listener)
.join();
WebSocket ws = client.newWebSocketBuilder()
.buildAsync(URI.create("wss://echo.websocket.org"), listener)
.join();
Best Practices :
=> Use HttpClient.newBuilder() for custom configuration (timeout, redirect, proxy).
=> Use BodyHandlers.ofString(), ofByteArray(), or ofFile() as needed.
=> Reuse the HttpClient instance (thread-safe, connection pooling).
=> Prefer asynchronous for high concurrency.=> Use BodyHandlers.ofString(), ofByteArray(), or ofFile() as needed.
Is join() mandatory in async HTTP client?
=> No — join() blocks the current thread until CompletableFuture completes. Use it in main methods to wait for result before exit. In servers, avoid it to keep non-blocking. Without join(), the async chain runs in background. Handle with exceptionally() for errors.
=> i.e use join() when you need to wait synchronously
How to make synchronous HTTP GET request ?
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.com")).build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.body());
HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.com")).build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
System.out.println(response.body());
How to make asynchronous HTTP GET ?
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
.thenApply(HttpResponse::body)
.thenAccept(System.out::println);
What is the use of Files.readString and Files.writeString in Java 11 ?
=> Read/write entire file as String.
=> Example : String content = Files.readString(path); Files.writeString(path, "text");
What is Collection.toArray(IntFunction) in Java 11 ?
=> It is used for converting collections to typed Arrays
=> type-safe array conversion
=> It uses constructor references like String[]::new
=> It creates correctly sized array internally
=> Syntax : Type[] array = list.toArray(Type[]::new);
For example, consider converting List to typedArray
Before Java,
String[] arr = (String[]) list.toArray(); // Unchecked cast warning (cast means checking type)
In the above code, toArray() → returns Object[] (So, it requires casting)
String[] arr = list.toArray(new String[list.size()]); // Wasteful if size wrong
Java 11 has solution for the above problem (check the below code),
// Best way in Java 11+
String[] array = list.toArray(String[]::new); // No cast, no warning
=> String[]::new is a constructor reference of IntFunction<String[]>.
=> The method internally calls generator.apply(list.size()) to create an array of exact size
=> Returns correctly typed array — no cast needed, no warning.
=> Complete Example :
import java.util.*;
public class ToArrayExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("Java", "Python", "C++");
// Java 11+ way — clean and type-safe
String[] array = list.toArray(String[]::new);
System.out.println(Arrays.toString(array)); // [Java, Python, C++]
System.out.println(array.getClass()); // class [Ljava.lang.String;
}
}
public class ToArrayExample {
public static void main(String[] args) {
List<String> list = Arrays.asList("Java", "Python", "C++");
// Java 11+ way — clean and type-safe
String[] array = list.toArray(String[]::new);
System.out.println(Arrays.toString(array)); // [Java, Python, C++]
System.out.println(array.getClass()); // class [Ljava.lang.String;
}
}
=> Note : It can be used for other types as well
=> String Array :
List<String> list = Arrays.asList("A", "B", "C");
String[] array = list.toArray(String[]::new);
String[] array = list.toArray(String[]::new);
=> Integer Array :
List<Integer> numbers = Arrays.asList(10, 20, 30);
Integer[] array = numbers.toArray(Integer[]::new);
Integer[] array = numbers.toArray(Integer[]::new);
=> Double Array :
List<Double> doubles = Arrays.asList(1.5, 2.7, 3.14);
Double[] array = doubles.toArray(Double[]::new);
Double[] array = doubles.toArray(Double[]::new);
=> Custom class (Employee) Array :
class Employee { String name; int salary; /* constructor, getters */ }
List<Employee> employees = Arrays.asList(
new Employee("Sachin", 600000),
new Employee("Virat", 500000)
);
Employee[] array = employees.toArray(Employee[]::new);
List<Employee> employees = Arrays.asList(
new Employee("Sachin", 600000),
new Employee("Virat", 500000)
);
Employee[] array = employees.toArray(Employee[]::new);
What is Predicate.not() in Java 11 ?
=> Negate Predicate (ie Inverse of Predicate)
=> Example: Predicate.not(String::isEmpty).
=> Negate Predicate (ie Inverse of Predicate)
=> Example: Predicate.not(String::isEmpty).
=> Predicate.not(String::isEmpty) returns a Predicate that is true for non-empty strings
=> Before Java 11, we had to write s -> !s.isEmpty()
_______________________________________________________________________
Practice the following coding exercises
- Use var for List, Map, Stream.
- var with diamond operator.
- var limitations (no initializer).
- String.isBlank() on empty/whitespace.
- String.lines() on multi-line → Stream<String>.
- strip(), stripLeading(), stripTrailing().
- String.repeat(5) on "Hello".
- Synchronous HTTP GET (print body from https://jsonplaceholder.typicode.com/posts/1).
- Asynchronous HTTP GET with thenAccept.
- Files.readString from test.txt (create file first).
- Files.writeString to file.
- list.toArray(String[]::new).
- Predicate.not for non-empty check.
- Combine var + HTTP Client.
- var with nested generics.
- 16–20. Mixed: Multi-line string → lines() → filter non-blank → collect toList, etc.