Java 11 - New Features
Local-Variable Syntax for Lambda Parameters
What is an?implicitly typed?lambda expression?
Let's start with an?explicitly?typed lambda expression. In the following example, explicit means that the data types of the lambda parameters?l?and?s?– i.e.,?List<String>?and?String?– are specified:
(List<String> l, String s) -> l.add(s);
However, the compiler can also derive types from the context so that the following –?implicitly?typed – notation is also permitted:
(l, s) -> l.add(s);
Since Java 11, you can use the?"var" keyword introduced in java 10?instead of the explicit types:
(var l, var s) -> l.add(s);
But why write "var" when you can omit the types completely, as in the example before?
The reason for this is annotations. If a variable is to be annotated, the annotation must be placed at the type – an explicit type or "var". An annotation is not permitted to be placed on the variable name.
If you want to annotate the variables in the above example, only the following notation was possible until now:
(@Nonnull List<String> l, @Nullable String s) -> l.add(s);
Java 11 now also allows the following, shorter variant with "var":
(@Nonnull var l, @Nullable var s) -> l.add(s);
The different notations must not be mixed. That means you must either specify the type for all variables, omit all types, or use "var" for all variables.
Which form you ultimately choose depends on the readability in the specific case and the style guidelines of your team.
HTTP Client (Standard)
JDK 11 includes the new?HttpClient?class, which significantly simplifies working with HTTP.
public String post(String url, String data) throws IOException, InterruptedException {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(data))
.build();
HttpResponse<String> response = client.send(request, BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new IOException("HTTP response status: " + response.statusCode());
}
return response.body();
}
The new?HttpClient?class is highly versatile:
- In the example above, we send a String via?BodyPublishers.ofString(). Using the methods?ofByteArray(),?ofByteArrays(),?ofFile(), and?ofInputStream()?of the same class, we can read the data to be sent from various other sources.
- Similarly, the?BodyHandlers?class, whose?ofString()?method we use to get the response as a String, can also return byte arrays and streams or store the received response in a file.
- HttpClient?also supports HTTP/2 and WebSocket, unlike the previous solution.
- Furthermore, in addition to the synchronous programming model shown above,?HttpClient?provides an asynchronous model. The?HttpClient.sendAsync()?method returns a?CompletableFuture, which we can then use to continue working asynchronously.
For example, an asynchronous variant of the?post?method might look like this:
public void postAsync(
String url, String data, Consumer<String> consumer, IntConsumer errorHandler) {
HttpClient client = HttpClient.newHttpClient();
HttpRequest request =
HttpRequest.newBuilder()
.uri(URI.create(url))
.header("Content-Type", "application/json")
.POST(BodyPublishers.ofString(data))
.build();
client
.sendAsync(request, BodyHandlers.ofString())
.thenAccept(
response -> {
if (response.statusCode() == 200) {
consumer.accept(response.body());
} else {
errorHandler.accept(response.statusCode());
}
});
}
领英推è
New String Methods
In Java 11, the?String?class has been extended with some helpful methods:
String.strip(), stripLeading(), stripTailing()
The?String.strip()?method removes all leading and trailing whitespaces from a String.
Isn't that what we already have the?String.trim()?method for?
Yes, with the following difference:
- trim()?removes all characters with a code point U+0020 or smaller. This includes, for example, "space", "tab", "newline", and "carriage return".
- strip()?removes those characters that?Character.isWhitespace()?classifies as whitespaces. On the one hand, these are some (but not all) characters with code point U+0020 or smaller. And on the other hand, characters defined in the Unicode Standard as spaces, line breaks, and paragraph separators (e.g., U+2002 – a space as wide as the letter 'n').
There are two variants of the method:?stripLeading()?removes only?leading?whitespaces,?stripTailing()?only?trailing?ones.
String.isBlank()
The new?String.isBlank()?method returns?true?if and only if the String contains only those characters that the?Character.isWhitespace()?method mentioned in the previous point classifies as whitespaces.
String.repeat()
You can use?String.repeat()?to repeatedly concatenate a String:
System.out.println(":-) ".repeat(10));
?
:-) :-) :-) :-) :-) :-) :-) :-) :-) :-)
String.lines()
The?String.lines()?method splits a String at line breaks and returns a Stream of all lines.
Here's a quick example:
Stream<String> lines = "foonbarnbaz".lines();
lines.forEachOrdered(System.out::println);
?
foo
bar
baz
Path.of()
Up to now, we had to create?Path?objects via?Paths.get()?or?File.toPath(). The introduction of interface default methods in Java 8 allowed JDK developers to integrate appropriate factory methods directly into the?Path?interface.
Since Java 11, you can create path objects as follows, for example:
// Relative path foo/bar/baz
Path.of("foo/bar/baz");
Path.of("foo", "bar/baz");
Path.of("foo", "bar", "baz");
// Absolute path /foo/bar/baz
Path.of("/foo/bar/baz");
Path.of("/foo", "bar", "baz");
Path.of("/", "foo", "bar", "baz");
As parameters, you can specify the whole path or parts of the path – in any combination, as shown in the example.