The Non-Jigsaw Improvements of Java 9
The Non-Jigsaw Improvements of Java 9
Jigsaw and modularity are big news with Java 9, but there's plenty more to get to know. Reactive Streams, concurrency, and the Java Shell are among the cool new tools.
Join the DZone community and get the full member experience.Join For Free
Atomist automates your software deliver experience. It's how modern teams deliver modern software.
Although the flagship feature of Java 9 is modularity, a large number of other enhancements are planned for this release. This article will provide an overview of those features that are scheduled for Java 9 release but are not as famous and glorious as the Jigsaw.
Reactive Streams are a contract for asynchronous stream processing with non-blocking back pressure.
Subscriber are two key concepts in the Reactive Streams specification.
Publisher is a producer of items (and related control messages) that will be received by
Subscribers, all these are done in a non-blocking way. Back pressure allows to control the amount of inflight data. That is, it will regulate the transfer between a slow publisher and a fast consumer and a fast publisher and a slow consumer.
Reactive Streams specification is comprised of four interfaces:
Publisher is a producer of items which
Subscribers can subscribe to.
Subscriber provides four callbacks:
onNext will be called every time a new item is available. There are also two terminal signals,
onComplete to signal the successful completion of the subscription, and
onError to signal an unrecoverable error encountered by a
Subscription encapsulates the communication between
Subscriber: one can request zero or more elements from the publisher or even cancel the subscription altogether.
Processor is a component that acts as both a
Reactive Streams will be integrated in Java 9. In
java.util.concurrent , there is a
Flow class that contains these four interfaces. Note that these are just the interfaces, Java 9 (or possibly any version of Java) won’t be shipped with an implementation for this specification. So in order to actually use a reactive API, at some point, you should use an implementation. Current notable implementations of this specification on the JVM are Project Reactor (which will be integrated in Spring 5), Akka Streams, and RxJava.
More Concurrency Updates
Suppose we have a
CompletableFuture that is going to fetch some movie recommendations from our fictional recommendation service. Now we want to add the capability of loading some static recommendations if the service couldn’t provide the expected result in a timely manner:
Here, if the recommendation service could provide the recommendations in less than 1 second, we’ll show those recommendations to the end user. Otherwise, we’ll make the poor user watch Fight Club one more time. The new
completeOnTimeout(T value, long timeout, TimeUnit unit) method completes the
CompletableFuture with the given value if it’s not completed before the given timeout.
If you don’t want to provide the static recommendation, you can simply raise a
TimeoutException with the
orTimeout(long timeout, TimeUnit unit) method:
Java 9 also will be shipped with some other enhancements to the
CompletableFuture API, which was introduced in Java 8. There was a
completedFuture static factory method in Java 8 to create a new
CompletableFuture that is already completed with the given value. If you want to create an already failed
CompletableFuture, you can use the new
failedFuture static factory method:
Also there will be
failedStage methods, which will create new
CompletionStages that is already completed or failed, respectively.
Convenient Factory Methods for Collections
The goal of JEP 269 is to:
Define library APIs to make it convenient to create instances of collections and maps with small numbers of elements, so as to ease the pain of not having collection literals in the Java programming language.
For example, in order to create a
List with few
Strings in it:
Or to create a
Map from singer name to his/her band name:
The same code can be refactored as:
The Java Shell
Java Shell or JShell is the Read Eval Print Loop (REPL) environment for Java. That is, it's an interactive tool to evaluate declarations, statements, and expressions of the Java programming language. To start experimenting with JShell, open up a terminal and just type
jshell is accessible from your
JShell is an interactive Java shell that accepts your Java code snippets and evaluates them in real time and tells you the result. So there is no need to create a
public static void main to test an API, anymore!
For starters, let’s declare a variable:
As you can see, semicolons are optional. JShell supports Tabcompletion, just type a few chars and hit Tab and JShell tries its best to complete that name:
When you did choose a method name, you can hit the Shift and Tab to see all overloaded versions of the chosen method:
Hit it one more time to see the Javadoc:
If you evaluate an expression and don’t assign it to a variable, it will be assigned to a Pseudo Variable, which starts with
$3 pseudo variable will hold the
foo value, you can make sure of that fact by:
List of three programming languages:
Now we’re going to just keep those languages whose name starts with the letter
Here JShell couldn’t find the
Collectors symbol. By default JShell provides a set of common imports:
Collectors isn’t part of those default imports, we should bring it to the scope:
Anyway, JShell is all about exploratory programming with features to ease interaction, including: a history with editing, tab-completion, automatic addition of needed terminal semicolons, and configurable predefined imports and definitions.
New IO Features
Probably the most familiar code snippet for every single Java developer is the following:
In Java 9, there is a
readAllBytes method for
InputStream which reads all remaining bytes from the input stream and returns a byte array containing the bytes read from that input stream. Finally After 20 years we can simply write:
There is also a
readNBytes(byte b, int off, int len) method which reads the requested number of bytes from the input stream into the given byte array.
Do you ever want an easy way to write contents of a Java
InputStream to an
OutputStream? The newly added
transferTo(OutputStream out) method will read all bytes from the input stream and writes the bytes to the given output stream in the order that they are read. So in order to write contents of a Java
InputStream to an
OutputStream, one can:
New HTTP Client
The other new addition to Java 9 is the new HTTP client API, which supports HTTP/2 and WebSocket. This client isn’t in the
java.base module, so we should declare a dependency to the
java.httpclient module in our
There is a
HttpRequest to represent an HTTP request which can be sent to a server:
By calling the
response() method you can send the request and block until a response comes from the server encapsulated as a
For more details on this new API, you can check out the Java 9: High-Level HTTP and WebSocket API post.
Optional, which first were introduced in Java 8, haven’t undergone any significant changes, but there will be some new and useful methods there.
Stream would have the
takeWhile methods to drop or take only elements that match the given
Predicate. The new
stream() method in
Optional can be used to convert the
Optional to a
Stream of, at most, one element. Also, the
ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction) method is useful for scenarios when you want to consume the optional value if it’s present or supply an empty action if it’s not.
LocalDate will have a
datesUntil(LocalDate endExclusive) method, which returns a sequential, ordered stream of dates, starting from this date and going to
endExclusive(exclusive) by an incremental step of one day. For example, in order to count the number of leap years between my birthday and current date:
For this particular scenario, using a 1-year step is more plausible (instead of default 1 day):
Sometimes in Java we had to write statements like:
Languages like Groovy are providing an Elvis operator, which is a shortening of the ternary operator:
Java doesn’t provide such a syntactic sugar but
Objects utility class will have
requireNonNullElseGet methods to kinda (not as smooth and cool as Elvis operator) alleviates that problem:
Published at DZone with permission of Ali Dehghani . See the original article here.
Opinions expressed by DZone contributors are their own.