Last Updated on August 20, 2023 by KnownSense
Oracle launched Java 11 in September 2018, just six months after the previous version, Java 10.
Java 11 is the first version that Oracle will support for a long time after Java 8. Oracle stopped giving support to Java 8 in January 2019.
Let’s explore some of the key features and changes to the common APIs that Java 11 introduced:
New String Methods:
Java 11 introduces some fresh methods to the String class, like isBlank, lines, strip, stripLeading, stripTrailing, and repeat.
Now, we’ll explore how to use these methods with example
Stream<String> lines()
: Returns a stream of lines extracted from this string, separated by line terminators.
A line terminator is one of the following: a line feed character “\n” (U+000A), a carriage return character “\r” (U+000D), or a carriage return followed immediately by a line feed “\r\n” (U+000D U+000A).
boolean isBlank()
: Returns true if the string is empty or contains only white space codepoints, otherwise false.
String strip()
: Returns a string whose value is this string, with all leading and trailing white space removed. If this String object represents an empty string, or if all code points in this string are white space, then an empty string is returned.
String stripLeading()
: Returns a string whose value is this string, with all leading white space removed.
String stripTrailing()
: Returns a string whose value is this string, with all trailing white space removed.
String repeat(int count)
: Returns a string whose value is the concatenation of this string repeated count times.
Code to filters, removes whitespace, and collects non-blank lines from a multiline string.
import java.util.List;
import java.util.stream.Collectors;
public class Java11_Example {
public static void main(String args[]){
String multilineString = "CodingKnownsense helps \n \n developers \n explore Java";
List<String> lines = multilineString.lines()
.filter(line -> !line.isBlank())
.map(String::strip)
.collect(Collectors.toList());
System.out.println(lines);
}
}
Output:
[CodingKnownsense helps, developers, explore Java]
Repeat Example
System.out.println("hello ".repeat(5));
Output:
hello hello hello hello hello
New File Methods:
We can use the new readString and writeString static methods from the Files class:
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Java11_Example {
public static void main(String args[]) throws IOException {
String tempDir="src/main/resources";
Path filePath = Files.writeString(Files.createTempFile(Path.of(tempDir), "demo", ".txt"), "Sample text");
String fileContent = Files.readString(filePath);
}
}
Output:
A new .txt file created with content “Sample text” and name having prefix demo in given directory as shown below
Collection to an Array
The java.util.Collection interface now has a default toArray method that accepts an IntFunction parameter.
List sampleList = Arrays.asList("Coding", "Knownsense");
String[] sampleArray = (String[]) sampleList.toArray(String[]::new);
Not Predicate Method
A static not method has been added to the Predicate interface.
static <T> Predicate<T> not(Predicate<? super T> target)
: Returns a predicate that is the negation of the supplied predicate. This is accomplished by returning result of the calling target.negate().
We will modify the example 1 in this page to use not Method
import java.util.List;
import java.util.stream.Collectors;
public class Java11_Example {
public static void main(String args[]){
String multilineString = "CodingKnownsense helps \n \n developers \n explore Java";
List<String> lines = multilineString.lines()
.filter(Predicate.not(String::isBlank))
.map(String::strip)
.collect(Collectors.toList());
System.out.println(lines);
}
}
Output:
[CodingKnownsense helps, developers, explore Java]
Local-Variable Syntax for Lambda
Support for using the local variable syntax (var keyword) in lambda parameters was added in Java 11. we can write code more simply by letting the computer figure out the type of a variable.
For example:
Before (old way):String message = "Hello, Java!";
With local-variable type inference (new way):var message = "Hello, Java!";
Here, the compiler understands that message
is a String without us explicitly saying it.
Why should we consider using “var” for lambda parameters instead of leaving out the types?
To apply modifiers to both local variables and lambda formal parameters without sacrificing code conciseness.
(@Nonnull var s1, @Nullable var s2) -> s1 + s2
We cannot use such annotations without specifying the types.
HTTP Client
java.net.http package introduced in Java 9, has now become a standard feature in Java 11.
The new HTTP API improves overall performance and provides support for both HTTP/1.1 and HTTP/2.
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_2)
.connectTimeout(Duration.ofSeconds(20))
.build();
HttpRequest httpRequest = HttpRequest.newBuilder()
.GET()
.uri(URI.create("http://localhost:" + port))
.build();
HttpResponse httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
Nest Based Access Control
Before Java 11 this was possible:
public class Main {
public void myPublic() {
}
private void myPrivate() {
}
class Nested {
public void nestedPublic() {
myPrivate();
}
}
}
private method of the main class is accessible from the above-nested class in the above manner. But if we use Java Reflection, it will give an IllegalStateException
.
Method method = ob.getClass().getDeclaredMethod("myPrivate");
method.invoke(ob);
Java 11 nested access control addresses this concern in reflection. java.lang.Class
introduces three methods in the reflection API: getNestHost()
, getNestMembers()
, and isNestmateOf()
.
Running Java Files
A major change is that we don’t need to compile the Java source files with javac explicitly anymore:
$ javac HelloWorld.java
$ java HelloWorld
Hello Java 8!
Instead, we can directly run the file using the java command:
$ java HelloWorld.java
Hello Java 11!