Java 9 Real - Time

You might also like

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 57

Java 9 Features and Enhancements

In this article, we will discuss newly added Java 9 features. Oracle has released Open JDK 9 with
the several new features and improvements on July 27, 2017.

Java 9 is bringing lots of new enhancements which are going to affect your
programming style and habit, in big way. The biggest change is the modularization of
Java. It’s another big change after Lambdas in Java 8. In this article, I am listing down
changes which will be part of JDK 9 release.

What is new in Java 9

Java platform module system


Interface Private Methods
HTTP 2 Client
JShell - REPL Tool
Platform and JVM Logging
Process API Updates
Collection API Updates
Stream API Improvements
Multi-Release JAR Files
@Deprecated Tag Changes
Stack Walking
Java Docs Updates
Miscellaneous Other Features

Java platform module system

JPMS (Java Platform Module System) is the core highlight of new Java 9 release. It is also
known as Project Jigshaw. A module is new construct like we already have packages. An
application, developed using new modular programming, can be seen as collection of
interacting modules with a well-defined boundaries and dependencies between those
modules.

The JPMS consists of providing support for writing modular applications as well as
modularizing the JDK source code as well. JDK 9 is coming with around 92 modules
(changes are possible in GA release). Java 9 Module System has a “java.base” Module.
It’s known as Base Module. It’s an Independent module and does NOT dependent on
any other modules. By default, all other modules are dependent on “java.base”.
In java modular programming-

1. A module is typically just a jar file that has a module-info.class file at the root.
2. To use a module, include the jar file into modulepath instead of the classpath. A
modular jar file added to classpath is normal jar file and module-info.class file will be
ignored.

Typical module-info.java classes looks like this:


module helloworld {

    exports com.howtodoinjava.demo;

  

module test {

    requires helloworld;

Read More: Java 9 Modules Tutorial

Interface Private Methods

Java 8 allowed you to write default methods in interfaces, and it was widely appreciated
feature. So after this, interfaces only lack few things and only non-private methods was
one of them. Java 9 onward, you are allowed to include private methods in interfaces.

These private methods will improve code re-usability inside interfaces. Foe example, if
two default methods needed to share code, a private interface method would allow
them to do so, but without exposing that private method to it’s implementing classes.

Using private methods in interfaces have four rules :

1. Private interface method cannot be abstract.


2. Private method can be used only inside interface.
3. Private static method can be used inside other static and non-static interface methods.
4. Private non-static methods cannot be used inside private static methods.

An example of using private methods in interfaces –

public interface CustomCalculator
{

    default int addEvenNumbers(int... nums) {

        return add(n -> n % 2 == 0, nums);

    }

  

    default int addOddNumbers(int... nums) {

        return add(n -> n % 2 != 0, nums);

    }

  

    private int add(IntPredicate predicate, int... nums) {

        return IntStream.of(nums)

                .filter(predicate)

                .sum();

    }

Java 9 – Private Methods in Interface

HTTP/2 Client

HTTP/1.1 client was released on 1997. A lot has changed since. So for Java 9 a new API
been introduced that is cleaner and clearer to use and which also adds support for
HTTP/2. New API uses 3 major classes i.e. HttpClient, HttpRequest and HttpResponse.

To make a request, it is as simple as getting your client, building a request and sending
it as shown below.
HttpClient httpClient = HttpClient.newHttpClient();

HttpRequest httpRequest =
HttpRequest.newBuilder().uri(newURI("//howtodoinjava.com/")).GET().build();

HttpResponse<String> httpResponse = httpClient.send(httpRequest,


HttpResponse.BodyHandler.asString());

System.out.println( httpResponse.body() );

Above code looks much cleaner and readable.


New API also support Async HTTP requests using httpClient.sendAsync() method. It
returns CompletableFuture object which can be used to determine whether the request
has been completed or not. It also provide you access to the HttpResponse once request
is completed. Best part is that if you desire you can even cancel the request before it
completes. e.g.
if(httpResponse.isDone()) {

    System.out.println(httpResponse.get().statusCode());

    System.out.println(httpResponse.get().body());

} else {

    httpResponse.cancel(true);

JShell – REPL Tool

JShell is new command line interactive tool shipped with JDK 9 distribution [JEP 222] to
evaluate declarations, statements and expressions written in Java. JShell allows us to
execute Java code snippets and get immediate results without having to create a
solution or project.

Jshell is much like what we have command window in linux OS. Difference is that JShell
is Java specific. It has lots of other capabilities, other than executing simple code
snippets. e.g.

 Launch inbuilt code editor in separate window


 Launch code editor of your choice in separate window
 Execute code when Save operation happen in these external editors
 Load pre-written classes from file system

Java 9 JShell Tutorial

Platform and JVM Logging

JDK 9 has improved logging in platform classes (JDK classes) and JVM components,
through a new loging API. It lets you specify a logging framework of your choice
(e.g. Log4J2) as logging backend for logging messages from JDK classes. There are few
things you should know about this API:
1. The API is meant to be used by the classes in the JDK, not by application classes.
2. For your application code, you will continue using other logging APIs as before.
3. The API does not let you configure the logger programmatically.

The API consists of the following:

 A service interface, java.lang.System.LoggerFinder, which is an abstract static class


 An interface, java.lang.System.Logger, which provides the logging API
 An overloaded method getLogger() in the java.lang.System class, which returns a
logger instance.

JDK 9 also added a new command-line option, -Xlog , that gives you a single point of
access to all messages logged from all classes of the JVM. The following is the syntax to
use the -Xlog option:

-Xlog[:][:[][:[][:]]]

All options are optional. If a preceding part in -Xlog is missing, you must use a colon for
that part. For example, -Xlog::stderr indicates that all parts are defaulted, output wich
is set as stderr.

I will cover this topic in deep, in a separate post.

Process API Updates

Prior to Java 5, the only way to spawn a new process was to use
the Runtime.getRuntime().exec()method. Then in Java 5, ProcessBuilder API was
introduced which supported a cleaner way of spawning new processes. Now Java 9 is
adding a new way of getting information about current and any spawned process.

To get information of any process, now you should


use java.lang.ProcessHandle.Info interface. This interface can be useful in getting lots
of information e.g.

 the command used to start the process


 the arguments of the command
 time instant when the process was started
 total time spent by it and the user who created it

ProcessHandle processHandle = ProcessHandle.current();


ProcessHandle.Info processInfo = processHandle.info();

 
System.out.println( processHandle.getPid() );

System.out.println( processInfo.arguments().isPresent() );

System.out.println( pprocessInfo.command().isPresent() );

System.out.println( processInfo.command().get().contains("java") );

System.out.println( processInfo.startInstant().isPresent() );

To get the information of a new spawned process, use process.toHandle() method to


get ProcessHandle instance. Rest all of things are as above.
String javaPrompt = ProcessUtils.getJavaCmd().getAbsolutePath();

ProcessBuilder processBuilder = new ProcessBuilder(javaPrompt, "-version");

Process process = processBuilder.inheritIO().start();

ProcessHandle processHandle = process.toHandle();

Also use ProcessHandle.allProcesses() to get a stream of ProcessHandle of all


processes available in system.

To get the list of all child processes (direct as well as n-level deep),
use children() and descendants()method.
Stream<ProcessHandle> children    = ProcessHandle.current().children();

Stream<ProcessHandle> descendants = ProcessHandle.current().descendants();

Collection API Updates

Since Java 9, you can create immutable collections such as immutable list, immutable set
and immutable map using new factory methods. e.g.

import java.util.List;

  

public class ImmutableCollections

    public static void main(String[] args)

    {
        List<String> namesList = List.of("Lokesh", "Amit", "John");

 
        Set<String> namesSet = Set.of("Lokesh", "Amit", "John");

 
        Map<String, String> namesMap = Map.ofEntries(

                                    Map.entry("1", "Lokesh"),

                                    Map.entry("2", "Amit"),

                                    Map.entry("3", "Brian"));

    }

Java 9 Collections API Improvements

Stream API Improvements

Java 9 has introduced two new methods to interact with Streams


i.e. takeWhile / dropWhile methods. Additionally, it has added two overloaded methods
i.e. ofNullable and iterate methods.

The new methods takeWhile and dropWhile allow you to get portions of a stream based


on a predicate.

1. On an ordered stream, takeWhile returns the “longest prefix” of elements taken from


the stream that match the given predicate, starting at the beginning of the
stream. dropWhile returns the remaining items which were not matched by takeWhile.
2. On an un-ordered stream, takeWhile returns a subset of the stream’s elements that
match the given predicate (but not all), starting at the beginning of the
stream. dropWhile returns remaining stream elements after dropping subset of elements
that match the given predicate.

Similarily, till Java 8, you cannot have null value in a stream. It would have


caused NullPointerException. Since Java 9, Stream.ofNullable() method lets you create
a single-element stream which wraps a value if not null, or is an empty stream
otherwise. Technically, Stream.ofNullable() is very similar to null condition check, when
talking in context of stream API.

Java 9 Stream API Improvements


Multi-Release JAR Files

This enhancement is related to how you package application classes in jar files.
Previously, you had to package all classes into a jar file and drop in the classpath of the
another application, which wish to use it.

Using multi-release feature, now a jar can contains different versions of a class –
compatible to different JDK releases. The information regarding different versions of a
class, and in which JDK version which class shall be picked up by class loaded, is stored
in MANIFEST.MF file. In this case, MANIFEST.MFfile includes the entry Multi-Release:
true in its main section.

Furthermore, META-INF contains a versions subdirectory whose integer-named


subdirectories — starting with 9 (for Java 9) — store version-specific class and resource
files. e.g.

JAR content root


A.class
B.class
C.class
D.class
META-INF
MANIFEST.MF
versions
9
A.class
B.class

Let’s assume that in JDK 10, A.class is updated to leverage some Java 10 features, then
this Jar file can be updated like this:

JAR content root


A.class
B.class
C.class
D.class
META-INF
MANIFEST.MF
versions
9
A.class
B.class
10
A.class

It looks really promising step to solve the dependency hell often seen in large
application where jars with different versions are not compatible with each other. This
feature can be a big help to tackle those scenarios.

@Deprecated Tag Changes

From Java 9, @Deprecated annotation will have two attributes i.e. forRemoval and since.

1. forRemoval – Indicates whether the annotated element is subject to removal in a future


version.
2. since – It returns the version in which the annotated element became deprecated.

It is strongly recommended that the reason for deprecating a program element be


explained in the documentation, using the @deprecated javadoc tag. The
documentation should also suggest and link to a recommended replacement API, if
applicable. A replacement API often has subtly different semantics, so such issues should
be discussed as well.

Stack Walking

The stack is a Last-In-First-Out (LIFO) data structure. At JVM level, a stack stores frames.
A new frame is created and pushed to the top of the stack each time a method is
invoked. A frame is destroyed (popped out of stack) when the method invocation
completes. Each frame on a stack contains its own array of local variables, as well as its
own operand stack, return value, and reference to the runtime constant pool of the
current method’s class.

In a given thread, only one frame is active at any point. The active frame is known as the
current frame and its method is known as the current method . [Read More]

Till Java 8, StackTraceElement represents a stack frame. To get complete stack, you had
to use Thread.getStackTrace() and Throwable.getStackTrace(). It returned an array
of StackTraceElementwhich you can iterate to get required information.

In Java 9, a new class StackWalker has been introduced. The class provides easy and
efficient stack walking using sequential stream of stack frames for the current thread.
The StackWalker class is very efficient because it evaluates the stack frames lazily.
// Prints the details of all stack frames of the current thread

 
StackWalker.getInstance().forEach(System.out::println);

There are other lots of things you can do with this stream, which we will cover in some
other decdicated post.

Java Docs Updates

Java 9 enhances the javadoc tool to generate HTML5 markup. It currently generates


pages in HTML 4.01.

In order to generate a HTML5 Javadoc, the parameter -html5 needs to go in the


command line arguments. To generate the document on the command line, you would
run:

javadoc [options] [packagenames] [sourcefiles] [@files]

Using HTML5 confers the benefits of the easier HTML5 structure. It also implements
the WAI-ARIA standard for accessibility. This aims to make it easier for people with
physical or visual impairments to access javadocs pages using tools such as screen
readers.

JEP 225 gives the ability to search a javadoc for program elements and tagged words
and phrases.

The following will be indexed and searchable:

 Declared names of modules


 Packages
 Types and members
 The simple name of method parameter types

This is implemented client side, with a new search.js Javascript file, along with indexes
generated when the javadoc is generated. A search box is available on the generated
HTML5 API pages.

Please note that Search option will be added by default, but can be turned off with the
argument: -noindex.
Miscellaneous Other Features

There are other features as well in Java 9, which I am listing down here for quick
reference. We will discuss all these features in coming posts.

 Reactive Streams API


 GC (Garbage Collector) Improvements
 Filter Incoming Serialization Data
 Deprecate the Applet API
 Indify String Concatenation
 Enhanced Method Handles
 Compact Strings
 Parser API for Nashorn

Java 9 – Compact Strings Improvement


[JEP 254]
Till Java 8, String in java were internally represented by char[]. Each char is stored in 2
bytes in memory. JDK developers at oracle analyzed lots of client’s application heap
dumps and they noticed that most of the strings can be represented only using Latin-1
characters set. A latin-1 char can be stored in one byte, which is 50% (1 byte) less
than char data type storage.

So, the JDK developers defaulted the String classes internal storage


to byte[] from char[]. This has resulted in saving of lots of space in heap memory
because string objects take up really big portion of heap memory, generally. [Source]

You can control the usage of this feature in your application using -XX:-
CompactStrings parameters to java command.

String class BEFORE Java 9

Prior to Java 9, string data was stored as an array of chars. This required 16 bits for each
char.

public final class String

    implements java.io.Serializable, Comparable<String>, CharSequence {


 
    //The value is used for character storage.

    private final char value[];

 
}

String class AFTER Java 9

Starting with Java 9, strings are now internally represented using a byte array along with
a flag field for encoding references.

public final class String

    implements java.io.Serializable, Comparable<String>, CharSequence {

 
    /** The value is used for character storage. */

    @Stable

    private final byte[] value;

 
    /**

     * The identifier of the encoding used to encode the bytes in

     * {@code value}. The supported values in this implementation are

     *

     * LATIN1

     * UTF16

     *

     * @implNote This field is trusted by the VM, and is a subject to

     * constant folding if String instance is constant. Overwriting this

     * field after construction will cause problems.

     */

    private final byte coder;

 
}

‘java’ command reference

As we know that java command is used to launch a Java application. It can have many


parameters to customize the application runtime. One such command is below:

-XX:-CompactStrings

Disables the Compact Strings feature. By default, this option is enabled. When this
option is enabled, Java Strings containing only single-byte characters are internally
represented and stored as single-byte-per-character Strings using ISO-8859-1 / Latin-1
encoding. This reduces, by 50%, the amount of space required for Strings containing
only single-byte characters. For Java Strings containing at least one multibyte character:
these are represented and stored as 2 bytes per character using UTF-16
encoding. Disabling the Compact Strings feature forces the use of UTF-16
encoding as the internal representation for all Java Strings.

Cases where it may be beneficial to disable Compact Strings include the following:

1. When it’s known that an application overwhelmingly will be allocating multibyte


character Strings
2. In the unexpected event where a performance regression is observed in migrating from
Java SE 8 to Java SE 9 and an analysis shows that Compact Strings introduces the
regression

Java Modules
JPMS (Java Platform Module System) is the major enhancement in Java 9. It is also known
as Project Jigsaw. In this Java 9 modules example, we will learn about modules (in general) and
how your programming style will change in future when you will start writing modular code.
What is a Module in General

In any programming language, modules are (package-like) artifacts containing code,


with metadata describing the module and also its relation to other modules. Ideally,
these artifacts are recognizable from compile-time all the way through run-time. Any
application generally is combination of multiple modules which work together to
perform the business objectives.

In terms of application architecture, a module shall represent a specific business


capability. It should be self-sufficient for that capability, and should expose only
interfaces to use the module functionality. To complete its tasks, it may be dependent
on other modules, which it should declare explicitly.

So, in short, a module should adhere to three core principles –

 Strong Encapsulation
Encapsulation means to hide implementation details, which are are not essential to
know to use the module correctly. The purpose is that encapsulated code may
change freely without affecting users of the module.

 Stable Abstraction
Abstraction helps to expose module functionality using interfaces i.e. public APIs.
Anytime, you want to change the business logic or implementation inside module
code, changes will be transparent to the module users.

 Explicit dependencies
Modules can be dependent on other modules as well. These external
dependencies must be part of the module definition itself. These dependencies
between modules are often represented as graphs. Once you see the graph at
application level, you will have better understanding of the application’s
architecture.

Introduction to Java 9 Modules

Before java 9, you had ‘packages‘ to group related classes as per business capabilities.
Along with packages, you had ‘access modifiers‘ to control what will be visible and what
will be hidden to other classes or packages. It has been working great so far. Java has
strong support for encapsulation and abstraction.

But, explicit dependencies is where things start to fall apart. In java, dependencies are
declared with ‘import‘ statements; but they are strictly ‘compile time’ constructs. Once
code is compiled, there is no mechanism to clearly state it’s runtime dependencies. In
fact, java runtime dependency resolution is so much problematic area that special tools
have been created to fight this problem e.g. gradle or maven. Also, few frameworks
started bundling their complete runtime dependencies as well e.g. Spring bootprojects.

With new Java 9 modules, we will have better capability to write well-structured


applications. This enhancement is divided into two area:

1. Modularize the JDK itself.


2. Offer a module system for other applications to use.

Java 9 Module System has a “java.base” Module. It’s known as Base Module. It’s an
Independent module and does NOT dependent on any other modules. By default, all other
modules dependent on “java.base”.

In java 9, modules helps you in encapsulating packages and manage dependencies. So


typically,

 a class is a container of fields and methods


 a package is a container of classes and interfaces
 a module is a container of packages

You will not feel any major difference between normal code and modular code if you
don’t know the specific things to look for. e.g.

1. A module is typically just a jar file that has a module-info.class file at the root.
2. To use a module, include the jar file into modulepath instead of the classpath. A
modular jar file added to classpath is normal jar file and module-info.class file will be
ignored.

How to Write Modular Code

After reading all above concepts, let’s see how modular code is written in reality. I am
using Netbeans IDE because it has good early support of Java 9 (as of today).
Create Java Modular Project

Create new modular project. I have created with name JavaAppOne.

Create Java Modular Project


Create Java Modular Project – Step 2

Create Java Modules

Now add one or two modules in this project.


Create New Module

I have added two modules helloworld and test. Let’s see their code and project
structure.

Java 9 Modules Project Structure


/helloworld/module-info.java

module helloworld {

}
HelloWorldApp.java

package com.howtodoinjava.demo;

public class HelloWorldApp {

    public static void sayHello() {

        System.out.println("Hello from HelloWorldApp");

    }

/test/module-info.java

module test {

TestApp.java

package com.test;

public class TestApp {

    public static void main(String[] args) {

        //some code

    }

So far, modules are independent. Now suppose, we want to


use HelloWorldApp.sayHello() method in TestApp class. If you try to use the class
without importing the module, you will get compile time error “package
com.howtodoinjava.demo is not visible”.

Export Packages and Import Module

To be able to import HelloWorldApp, you must first export ‘com.howtodoinjava.demo’


package from helloworld module and then include helloworld module in test module.
module helloworld {

    exports com.howtodoinjava.demo;
}

 
module test {

    requires helloworld;

In above code, requires keyword indicates a dependency and exports keyword


identifies the packages which are available to be exported to other modules. Only when
a package is explicitly exported, it can be accessed from other modules. Packages inside
a module that are not exported, are inaccessible from other modules by default.

Now you will be able to use HelloWorldApp class inside TestApp class.

package com.test;

import com.howtodoinjava.demo.HelloWorldApp;

public class TestApp {

    public static void main(String[] args) {

        HelloWorldApp.sayHello();

    }

 
Output:

 
Hello from HelloWorldApp

Lets look at the modules graph a well.


Module Graph

Java JShell Tutorial with Examples


JShell is new command line interactive tool shipped with JDK 9 distribution [JEP 222] to
evaluate declarations, statements and expressions written in Java. JShell allows us to execute
Java code snippets and get immediate results without having to create a solution or project.

Launching JShell

The very first thing is to have JDK 9 installed into your machine. Download JDK 9 from
this link, and install it.

Go to installation location and look into /jdk-9/bin folder. You will find


the jshell.exe file in here.
JShell location in JDK 9

Now launch a new command window and check the java version.
>> java -version

It should point to JDK 9 version. If it is not then update environment


properties JAVA_HOME and PATHwith corresponding values.
JAVA_HOME=C:\Program Files\Java\jdk-9

PATH=C:\Program Files\Java\jdk-9\bin    //Path till bin folder

Now again launch new command prompt window and type command jshell. It will
change the cursor to jshell.
Jshell Launched Window

Congratulations, you are ready to play in JShell REPL (Read-Eval-Print Loop).

Writing Java Code

Jshell allow to create small code snippets and test them without requiring to create and
build a complex project. And that’s how it should be used. Working on JShell is kept
easy to make it usable and fast. Let’s see how?

Variables

You can define variables just like you do in real programming. Only difference is that
you don’t have to write a class or main method to start with.

jshell> int i = 10;

i ==> 10

To print the value of variable, just type the variable name and hit ENTER. It will print
the value of variable.
jshell> i

i ==> 10

To reassign a variable to new value, simply do it as normal way.


jshell> i=20;

i ==> 20

To list all the declared variables, use command /vars.


jshell> /vars

|    int i = 20

|    int j = 30

Wo
rking with Variables in JShell

Methods

Much like variables, methods are also straightforward.

To create method in jshell, define method with retrun type, method name, parameters
and method body. Access modifiers are not required.

jshell> int sum (int a, int b) {

   ...> return a+b;

   ...> }

|  created method sum(int,int)

To list all defined methods, use command /methods.


jshell> /methods

|    int sum(int,int)

To call the method, call it like normal programming.


jshell> sum(2,2)

$6 ==> 4

If you want to view the method code, use /list command. It will show the current
method sourcecode. T
jshell> /list sum

1 : int sum (int a, int b) {

   return a+b;

   }

To change the method code, you will need to rewrite the new modified code, with same
method name.

jshell> int sum (int a, int b) {

   ...> int c = a+b;

   ...> return c;

   ...> }

|  modified method sum(int,int)

 
jshell> /list sum

   3 : int sum (int a, int b) {

       int c = a+b;

       return c;

       }
Working with Methods in JShell

Please keep in mind the method overloading rules. It you changed the method parameters
count or their data types, then it will be a new method and there will be two methods registered
in jshell.

Edit Code in JShell Edit Pad

By the time, you are working in few lines of code, JShell inline editor is good enough.
But when you code start getting bigger then you might need a file editor to modify your
code.

Here you can use JShell edit pad. To launch edit pad, use /edit command with method
name.
JShell Edit Pad

Here change the method code as you want and click on Accept button. Modified code
will be updated in Jshell and you will get confirmation message in prompt. You can
change code as many time times as you like, save it and then exit the window.

Save Operation in Jshell Edit Pad

Launch Code in External Editor

Edit pad is really good enough for most of the needs, still if you like to code on any
particular editor then you can use it as well. JShell allows to easily configure any external
editor to edit the code snippets. You just need to get the complete path to the editor
we want to use and run /set editorcommand in JShell to configure the editor.
/set editor "C:\\Program Files\\Sublime Text 3\\sublime_text.exe"

Now execute the /edit command again. Now it will open the code in sublime editor.

Launch Sublime Editor from JShell

Feel free to edit the code and save you did in edit pad.

Load Code from External Files

Many times, you will have some code already written in any java file and you would like
to execute it into JShell. To load file in JShell, use /open command.

Let’s say I have one file Demo.java in c://temp folder. It’s content is:

int i1 = 10;

int i2 = 20;

int i3 = 30;
int i4 = 40;

int sum(int a, int b) {

    return a+b;

int sum(int a, int b, int c) {

    return a+b;

Now let’s load the file in JShell.


/open c:\\temp\\demo.java

Verify the variable and methods loaded in Jshell.

Java Code loaded in JShell

That’s all you must know while working with JShell REPL tool in Java 9.
Java Stream of Dates with
LocalDate.datesUntil()

Date/Time handling always been a pain area for java developers. The new Date-Time API
added in Java 8 changed the way, you interact with dates in java. It was a very powerful
and much needed improvement. The only thing missing was, getting a stream of dates
having some common difference between two subsequent dates (though it was possible
but there was no easy way).

Java 9 has introduced a new method LocalDate.datesUntil() which can give a stream


on dates. Using datesUntil() makes it easy to create dates streams with fixed offset.

Syntax of LocalDate.datesUntil()

This method has two overloaded forms:


Stream<LocalDate> datesUntil(LocalDate end)

Stream<LocalDate> datesUntil(LocalDate end, Period step)

The first version (i.e. without a Period) internally calls the second method
with Period.ofDays(1) and generates stream of dates with difference of 1 day in
between.

Date Stream Example with LocalDate.datesUntil()

Creating a stream of dates is very simple and straightforward.

import java.time.LocalDate;

import java.time.Period;

import java.util.List;

import java.util.stream.Collectors;

public class Java9StreamExamples {
 

    public static void main(String[] args) {

        System.out.println( getDaysInJava9(LocalDate.now(),
LocalDate.now().plusDays(10)) );

        System.out.println( getDaysInJava9Weeks(LocalDate.now(),
LocalDate.now().plusWeeks(10)) );

    }

     

    //Stream of dates with 1 day difference

    public static List<LocalDate> getDaysInJava9(LocalDate start, LocalDate end) {

        return start.datesUntil(end).collect(Collectors.toList());

    }

     

    //Stream of dates with 1 week difference

    public static List<LocalDate> getDaysInJava9Weeks(LocalDate start, LocalDate end) {

        return start.datesUntil(end, Period.ofWeeks(1)).collect(Collectors.toList());

    }

 
Output:

 
[2017-07-31, 2017-08-01, 2017-08-02, 2017-08-03, 2017-08-04,

2017-08-05, 2017-08-06, 2017-08-07, 2017-08-08, 2017-08-09]

 
[2017-07-31, 2017-08-07, 2017-08-14, 2017-08-21, 2017-08-28,

2017-09-04, 2017-09-11, 2017-09-18, 2017-09-25, 2017-10-02]
Date Stream in Java 8

If you have still not adapted Java 9, then you can use given below method method to
generate Date streams. This code is compatible to Java 8.

import java.time.LocalDate;

import java.time.Period;

import java.util.List;

import java.util.stream.Collectors;

import java.util.stream.Stream;

public class Java9StreamExamples {

    public static void main(String[] args)

    {

        System.out.println( getDaysInJava8(LocalDate.now(), 10) );

    }

 
    //Stream of dates with 1 day difference

    public static List<LocalDate> getDaysInJava8(LocalDate start, int days)

    {

        return Stream.iterate(start, date -> date.plusDays(1))

                .limit(days)

                .collect(Collectors.toList());

    }

 
Output:

 
[2017-07-31, 2017-08-01, 2017-08-02, 2017-08-03, 2017-08-04,

2017-08-05, 2017-08-06, 2017-08-07, 2017-08-08, 2017-08-09]
Java 9 Stream API Improvements

 java 9 improvements in Stream API


i.e. takeWhile / dropWhile methods, ofNullable and iterate methods with examples.

Limiting Stream with takeWhile() and dropWhile() methods

The new methods takeWhile and dropWhile allow you to get portions of a stream based


on a predicate. Here a stream can be either ordered or unordered, so :

1. On an ordered stream, takeWhile returns the “longest prefix” of elements taken from


the stream that match the given predicate, starting at the beginning of the stream.
2. On an un-ordered stream, takeWhile returns a subset of the stream’s elements that
match the given predicate (but not all), starting at the beginning of the stream.

The dropWhile method does the opposite of takeWhile method.

1. On an ordered stream, dropWhile returns remaining items after the “longest prefix” that


match the given predicate.
2. On an un-ordered stream, dropWhile returns remaining stream elements after dropping
subset of elements that match the given predicate.

takeWhile and dropWhile Example

In this example, we have list of chars from ‘a’ to ‘i’. I want all chars which may appear
before char ‘d’ in iteration.
List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i");

 
List<String> subset1 = alphabets
        .stream()

        .takeWhile(s -> !s.equals("d"))

        .collect(Collectors.toList());

 
System.out.println(subset1);

 
Output:

 
[a, b, c]

As stated before, dropWhile acts opposite to takeWhile method so in above example, if


used, it will return all characters which were left by takeWhile predicate.
List<String> alphabets = List.of("a", "b", "c", "d", "e", "f", "g", "h", "i");

 
List<String> subset2 = alphabets

        .stream()

        .dropWhile(s -> !s.equals("d"))

        .collect(Collectors.toList());

 
System.out.println(subset2);

 
Output:

 
[d, e, f, g, h, i]

Overloaded Stream iterate method

iterate() methods used for creating a stream which starts with a single element (the
seed), and subsequent elements are produced by successively applying the unary
operator. The result is an infinite stream. To terminate the stream, a limit or some other
short-circuiting function, like findFirstor findAny is used.

The iterate method in Java 8 has the signature:


static Stream iterate(final T seed, final UnaryOperator f)

In Java 9, new overloaded version of iterate takes a Predicate as the second argument:

static Stream iterate(T seed, Predicate hasNext, UnaryOperator next)

Let’s see the difference is use of iterate method from java 8 to java 9.

iterate method in Java 8


List<Integer> numbers = Stream.iterate(1, i -> i+1)

                            .limit(10)

                            .collect(Collectors.toList());

         

System.out.println(numbers);

 
Output:

 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

iterate method in Java 9


List<Integer> numbers = Stream.iterate(1, i -> i <= 10 ,i -> i+1)

                                .collect(Collectors.toList());

 
System.out.println(numbers);

 
Output:

 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

In above examples, the first stream is the Java 8 way of using iterate with a limit. The
second one uses a Predicate as the second argument.
New Stream ofNullable() method

Until Java 8, you cannot have null value in a stream. It would have


caused NullPointerException.

In Java 9, the ofNullable method lets you create a single-element stream which wraps


a value if not null, or is an empty stream otherwise.
Stream<String> stream = Stream.ofNullable("123");

System.out.println(stream.count());

 
stream = Stream.ofNullable(null);

System.out.println(stream.count());

 
Output:

 
1

Here, the count method returns the number of non-empty elements in a stream.

Technically, Stream.ofNullable() is very similar to null condition check, when talking in


context of stream API.
Immutable Collections with Factory
Methods in Java 9

Learn to create immutable collections such as immutable list, immutable


set and immutable map using new factory methods in Java 9.

Create Immutable List

Use List.of() static factory methods to create immutable lists. It has following different


overloaded versions –

static <E> List<E>  of()

static <E> List<E>  of(E e1)

static <E> List<E>  of(E e1, E e2)

static <E> List<E>  of(E e1, E e2, E e3)

static <E> List<E>  of(E e1, E e2, E e3, E e4)

static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5)

static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6)

static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)

static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)

static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)

static <E> List<E>  of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

//varargs

static <E> List<E>  of(E... elements)

The List instances created by these methods have the following characteristics:


1. These lists are immutable. Elements cannot be added, removed, or replaced in these lists.
Calling any mutator method (i.e. add, addAll, clear, remove, removeAll, replaceAll) will
always cause UnsupportedOperationException to be thrown.
2. They do not allow null elements. Attempts to add null elements result
in NullPointerException.
3. They are serializable if all elements are serializable.
4. The order of elements in the list is the same as the order of the provided arguments, or
of the elements in the provided array.

Lets see few examples of usage of immutable list.

package com.howtodoinjava;

import java.util.List;

public class ImmutableCollections

    public static void main(String[] args)

    {

        List<String> names = List.of("Lokesh", "Amit", "John");

         

        //Preserve the elements order

        System.out.println(names);

         

        //names.add("Brian"); //UnsupportedOperationException occured

         

        //java.lang.NullPointerException

        //List<String> names2 = List.of("Lokesh", "Amit", "John", null);

    }

 
Output:

 
[Lokesh, Amit, John]

Create Immutable Set

Set behave very similar to List with only few differences. e.g.

1. Set do not allow duplicate elements as well. Any duplicate element passed will result
in IllegalArgumentException.
2. The iteration order of set elements is unspecified and is subject to change.

All Set factory methods have the same signature as List.

static <E> Set<E>   of()

static <E> Set<E>   of(E e1)

static <E> Set<E>   of(E e1, E e2)

static <E> Set<E>   of(E e1, E e2, E e3)

static <E> Set<E>   of(E e1, E e2, E e3, E e4)

static <E> Set<E>   of(E e1, E e2, E e3, E e4, E e5)

static <E> Set<E>   of(E e1, E e2, E e3, E e4, E e5, E e6)

static <E> Set<E>   of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)

static <E> Set<E>   of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)

static <E> Set<E>   of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)

static <E> Set<E>   of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)

//varargs

static <E> Set<E>   of(E... elements)

Let’s see few examples of immutable sets.

import java.util.Set;

public class ImmutableCollections {

    public static void main(String[] args) {

        Set<String> names = Set.of("Lokesh", "Amit", "John");


         

        //Elements order not fixed

        System.out.println(names);

         

        //names.add("Brian"); //UnsupportedOperationException occured

         

        //java.lang.NullPointerException

        //Set<String> names2 = Set.of("Lokesh", "Amit", "John", null);

         

        //java.lang.IllegalArgumentException

        //Set<String> names3 = Set.of("Lokesh", "Amit", "John", "Amit");

    }

Create Immutable Map

Map factory methods are same as List or Set overloaded factory methods. Only


difference is that the signatures of the of methods take alternating keys and values as
arguments. e.g.

static <K,V> Map<K,V>   of()

static <K,V> Map<K,V>   of(K k1, V v1)

static <K,V> Map<K,V>   of(K k1, V v1, K k2, V v2)

...

...

static <K,V> Map<K,V>   ofEntries(Map.Entry<? extends K,? extends V>... entries)

Java 9 also provide a special method for creating Map entry instance.

static <K,V> Map.Entry<K,V> entry(K k, V v)

Let’s take an example of creating immutable Map in java 9.

import java.util.Map;
 

public class ImmutableCollections {

    public static void main(String[] args) {

        Map<String, String> names = Map.ofEntries(

                Map.entry("1", "Lokesh"),

                Map.entry("2", "Amit"),

                Map.entry("3", "Brian"));

         

        System.out.println(names);

         

        //UnsupportedOperationException

        //names.put("2", "Ravi");

    }

 
Output:

 
{1=Lokesh, 2=Amit, 3=Brian}

Clearly, new factory methods to create immutable collections in java 9 are very


much readable and easy to use.
Private Methods in Interface – Java 9

Java 9 onward, you are allowed to include private methods in interfaces. Using private
methods, now encapsulation is possible in interfaces as well.

Interfaces till Java 7

In Java 7 and all earlier versions, interfaces were very simple. They could only
contain public abstractmethods. These interface methods MUST be implemented by
classes which choose to implement the interface.

public interface CustomInterface {

    public abstract void method();

public class CustomClass implements CustomInterface {

    @Override

    public void method() {

        System.out.println("Hello World");

    }

    public static void main(String[] args){

        CustomInterface instance = new CustomClass();

        instance.method();

    }

 
Output:
 
Hello World

Static and defaults methods since Java 8

From Java 8, apart from public abstract methods, you can have public static methods


and public default methods.

public interface CustomInterface {

     

    public abstract void method1();

     

    public default void method2() {

        System.out.println("default method");

    }

     

    public static void method3() {

        System.out.println("static method");

    }

public class CustomClass implements CustomInterface {

 
    @Override

    public void method1() {

        System.out.println("abstract method");

    }

     

    public static void main(String[] args){

        CustomInterface instance = new CustomClass();

        instance.method1();
        instance.method2();

        CustomInterface.method3();

    }

 
Output:

abstract method

default method

static method

Access modifier ‘public’ is optional in all above interface method declarations. I have added
them to improve readability only.

Private methods since java 9

Since java 9, you will be able to add private methods and private static method in


interfaces.

These private methods will improve code re-usability inside interfaces. Foe example, if
two default methods needed to share code, a private interface method would allow
them to do so, but without exposing that private method to it’s implementing classes.

Using private methods in interfaces have four rules :

1. Private interface method cannot be abstract.


2. Private method can be used only inside interface.
3. Private static method can be used inside other static and non-static interface methods.
4. Private non-static methods cannot be used inside private static methods.

public interface CustomInterface {
     

    public abstract void method1();

     

    public default void method2() {

        method4();  //private method inside default method


        method5();  //static method inside other non-static method

        System.out.println("default method");

    }

     

    public static void method3() {

        method5(); //static method inside other static method

        System.out.println("static method");

    }

     

    private void method4(){

        System.out.println("private method");

    }

     

    private static void method5(){

        System.out.println("private static method");

    }

public class CustomClass implements CustomInterface {

 
    @Override

    public void method1() {

        System.out.println("abstract method");

    }

     

    public static void main(String[] args){

        CustomInterface instance = new CustomClass();

        instance.method1();

        instance.method2();

        CustomInterface.method3();
    }

 
Output:

abstract method

private method

private static method

default method

private static method

static method

Java 9 Private Interface Method Example

Let’s see a demo to understand the private interface method’s usage.

I am creating a calculator class with two functions. First function will accept some
integers and add all even numbers in it. Second function will accept some integers and
add all odd numbers in it.

CustomCalculator.java – Interface
import java.util.function.IntPredicate;

import java.util.stream.IntStream;

public interface CustomCalculator

    default int addEvenNumbers(int... nums) {

        return add(n -> n % 2 == 0, nums);

    }

    default int addOddNumbers(int... nums) {
        return add(n -> n % 2 != 0, nums);

    }

    private int add(IntPredicate predicate, int... nums) {

        return IntStream.of(nums)

                .filter(predicate)

                .sum();

    }

Main.java – Class
public class Main implements CustomCalculator {

    public static void main(String[] args) {

        CustomCalculator demo = new Main();

         

        int sumOfEvens = demo.addEvenNumbers(1,2,3,4,5,6,7,8,9);

        System.out.println(sumOfEvens);

         

        int sumOfOdds = demo.addOddNumbers(1,2,3,4,5,6,7,8,9);

        System.out.println(sumOfOdds);

    }

 
Output:

 
20

25
Summary

In short, java 9 private interface methods can be static or instance. In both cases, the


private method is not inherited by sub-interfaces or implementations. They are mainly
there to improve code re-usability within interface only – thus improving encapsulation.

Let’s revisit all the allowed method types in java 9.

METHOD TYPE SINCE WHEN

public abstract Java 7

public default Java 8

public static Java 8

private Java 9

private static Java 9

Java 9 Features with Examples


1. Java 9 REPL (JShell)
Oracle Corp has introduced a new tool called “jshell”. It stands for Java Shell and
also known as REPL (Read Evaluate Print Loop). It is used to execute and test
any Java Constructs like class, interface, enum, object, statements etc. very
easily.

We can download JDK 9 EA (Early Access) software from


https://jdk9.java.net/download/

G:\>jshell
| Welcome to JShell -- Version 9-ea
| For an introduction type: /help intro

jshell> int a = 10
a ==> 10

jshell> System.out.println("a value = " + a )


a value = 10
If you want to know more about REPL tool, Please go through Java 9 REPL
Basics (Part-1)and Java 9 REPL Features (Part-2).

2. Factory Methods for Immutable List, Set, Map and


Map.Entry
Oracle Corp has introduced some convenient factory methods to
create Immutable List, Set, Map and Map.Entry objects. These utility methods are
used to create empty or non-empty Collection objects.

In Java SE 8 and earlier versions, We can use Collections class utility methods
like unmodifiableXXX to create Immutable Collection objects. For instance, if we
want to create an Immutable List, then we can use Collections.unmodifiableList
met,hod.

However these Collections.unmodifiableXXX methods are very tedious and


verbose approach. To overcome those shortcomings, Oracle corp has added
couple of utility methods to List, Set and Map interfaces.

List and Set interfaces have “of()” methods to create an empty or no-empty
Immutable List or Set objects as shown below:
Empty List Example

List immutableList = List.of();


Non-Empty List Example

List immutableList = List.of("one","two","three");


Map has two set of methods: of() methods and ofEntries() methods to create an
Immutable Map object and an Immutable Map.Entry object respectively.

Empty Map Example

jshell> Map emptyImmutableMap = Map.of()


emptyImmutableMap ==> {}
Non-Empty Map Example

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2,


"two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}
If you want to read more about these utility methods, please go through the
following links:

o Java 9 Factory Methods for Immutable List


o Java 9 Factory Methods for Immutable Set
o Java 9 Factory Methods for Immutable Map and Map.Entry
 Private methods in Interfaces
In Java 8, we can provide method implementation in Interfaces using Default and
Static methods. However we cannot create private methods in Interfaces.

To avoid redundant code and more re-usability, Oracle Corp is going to introduce
private methods in Java SE 9 Interfaces. From Java SE 9 on-wards, we can write
private and private static methods too in an interface using ‘private’ keyword.

These private methods are like other class private methods only, there is no
difference between them.

public interface Card{


private Long createCardID(){
// Method implementation goes here.
}

private static void displayCardDetails(){


// Method implementation goes here.
}

}
If you want to read more about this new feature, please go through this link: Java
9 Private methods in Interface.

 Java 9 Module System


One of the big changes or java 9 feature is the Module System. Oracle Corp is
going to introduce the following features as part of Jigsaw Project.

o Modular JDK
o Modular Java Source Code
o Modular Run-time Images
o Encapsulate Java Internal APIs
o Java Platform Module System

Before Java SE 9 versions, we are using Monolithic Jars to develop Java-Based


applications. This architecture has lot of limitations and drawbacks. To avoid all
these shortcomings, Java SE 9 is coming with Module System.

JDK 9 is coming with 92 modules (may change in final release). We can use JDK
Modules and also we can create our own modules as shown below:

Simple Module Example

module com.foo.bar { }
Here We are using ‘module’ to create a simple module. Each module has a name,
related code and other resources.

To read more details about this new architecture and hands-on experience, please
go through my original tutorials here:

o Java 9 Module System Basics


o Java 9 Module Examples using command prompt
o Java 9 Hello World Module Example using Eclipse IDE
 Process API Improvements
Java SE 9 is coming with some improvements in Process API. They have added
couple new classes and methods to ease the controlling and managing of OS
processes.

Two new interfcase in Process API:

o java.lang.ProcessHandle
o java.lang.ProcessHandle.Info

Process API example

ProcessHandle currentProcess = ProcessHandle.current();


System.out.println("Current Process Id: = " +
currentProcess.getPid());
If you want to read more about this new API, please go through my original tutorial
at: Java SE 9: Process API Improvements.

 Try With Resources Improvement


We know, Java SE 7 has introduced a new exception handling construct: Try-
With-Resources to manage resources automatically. The main goal of this new
statement is “Automatic Better Resource Management”.

Java SE 9 is going to provide some improvements to this statement to avoid some


more verbosity and improve some Readability.

Java SE 7 example

void testARM_Before_Java9() throws IOException{


BufferedReader reader1 = new BufferedReader(new
FileReader("journaldev.txt"));
try (BufferedReader reader2 = reader1) {
System.out.println(reader2.readLine());
}
}
Java 9 example
void testARM_Java9() throws IOException{
BufferedReader reader1 = new BufferedReader(new
FileReader("journaldev.txt"));
try (reader1) {
System.out.println(reader1.readLine());
}
}
To read more about this new feature, please go through my original tutorial
at: Java 9 Try-With-Resources Improvements

 CompletableFuture API Improvements


In Java SE 9, Oracle Corp is going to improve CompletableFuture API to solve
some problems raised in Java SE 8. They are going add to support some delays
and timeouts, some utility methods and better sub-classing.

Executor exe = CompletableFuture.delayedExecutor(50L,


TimeUnit.SECONDS);
Here delayedExecutor() is static utility method used to return a new Executor that
submits a task to the default executor after the given delay.

To read more about this feature, please go through my original tutorial at: Java SE
9: CompletableFuture API Improvements

 Reactive Streams
Now-a-days, Reactive Programming has become very popular in developing
applications to get some beautiful benefits. Scala, Play, Akka etc. Frameworks
has already integrated Reactive Streams and getting many benefits. Oracle Corps
is also introducing new Reactive Streams API in Java SE 9.

Java SE 9 Reactive Streams API is a Publish/Subscribe Framework to implement


Asynchronous, Scalable and Parallel applications very easily using Java
language.

Java SE 9 has introduced the following API to develop Reactive Streams in Java-
based applications.

o java.util.concurrent.Flow
o java.util.concurrent.Flow.Publisher
o java.util.concurrent.Flow.Subscriber
o java.util.concurrent.Flow.Processor
Read more at Java 9 Reactive Streams.

 Diamond Operator for Anonymous Inner Class


We know, Java SE 7 has introduced one new feature: Diamond Operator to avoid
redundant code and verbosity, to improve readability. However in Java SE 8,
Oracle Corp (Java Library Developer) has found that some limitation in the use of
Diamond operator with Anonymous Inner Class. They have fixed that issues and
going to release as part of Java 9.

public List getEmployee(String empid){


// Code to get Employee details from Data Store
return new List(emp){ };
}
Here we are using just “List” without specifying the type parameter. To read more
details about this improvement, please go through my original tutorial at: Java SE
9: Diamond Operator improvements for Anonymous Inner Class

 Optional Class Improvements


In Java SE 9, Oracle Corp has added some useful new methods to
java.util.Optional class. Here I’m going to discuss about one of those methods with
some simple example: stream method

If a value present in the given Optional object, this stream() method returns a
sequential Stream with that value. Otherwise, it returns an Empty Stream.

They have added “stream()” method to work on Optional objects lazily as shown
below:

Stream<Optional> emp = getEmployee(id)


Stream empStream = emp.flatMap(Optional::stream)
Here Optional.stream() method is used convert a Stream of Optional of Employee
object into a Stream of Employee so that we can work on this result lazily in the
result code.

To understand more about this feature with more examples and to read more new
methods added to Optional class, please go through my original tutorial at: Java
SE 9: Optional Class Improvements
 Stream API Improvements
In Java SE 9, Oracle Corp has added four useful new methods to java.util.Stream
interface. As Stream is an interface, all those new implemented methods are
default methods. Two of them are very important: dropWhile and takeWhile
methods

If you are familiar with Scala Language or any Functions programming language,
you will definitely know about these methods. These are very useful methods in
writing some functional style code. Let us discuss about takeWhile utility method
here.

This takeWhile() takes a predicate as an argument and returns a Stream of subset


of the given Stream values until that Predicate returns false for the first time. If first
value does NOT satisfy that Predicate, it just returns an empty Stream.

jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5


)
.forEach(System.out::println);
1
2
3
4
To read more about takeWhile and dropWhile methods and other new methods,
please go through my original tutorial at: Java SE 9: Stream API Improvements

 Enhanced @Deprecated annotation


In Java SE 8 and earlier versions, @Deprecated annotation is just a Marker
interface without any methods. It is used to mark a Java API that is a class, field,
method, interface, constructor, enum etc.

In Java SE 9, Oracle Corp has enhanced @Deprecated annotation to provide


more information about deprecated API and also provide a Tool to analyse an
application’s static usage of deprecated APIs. They have add two methods to this
Deprecated interface: forRemoval and since to serve this information.

Read my original tutorial at: Java SE 9: Enhanced @Deprecated annotation to


see some useful examples.

 HTTP 2 Client
In Java SE 9, Oracle Corp is going to release New HTTP 2 Client API to support
HTTP/2 protocol and WebSocket features. As existing or Legacy HTTP Client API
has numerous issues (like supports HTTP/1.1 protocol and does not support
HTTP/2 protocol and WebSocket, works only in Blocking mode and lot of
performance issues.), they are replacing this HttpURLConnection API with new
HTTP client.

They are going to introduce new HTTP 2 Client API under “java.net.http” package.
It supports both HTTP/1.1 and HTTP/2 protocols. It supports both Synchronous
(Blocking Mode) and Asynchronous Modes. It supports Asynchronous Mode using
WebSocket API.

We can see this new API at:


http://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html

HTTP 2 Client Example

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new


URI("http://rams4java.blogspot.co.uk/2016/05/java-
news.html")
uri ==> http://rams4java.blogspot.co.uk/2016/05/java-
news.html

jshell> HttpResponse response =


HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " +


response.body(asString()))
Please go through my original tutorial at: Java SE 9: HTTP 2 Client to understand
HTTP/2 protocol & WebSocket, Benefits of new API and Drawbacks of OLD API
with some useful examples.

 Multi-Resolution Image API


In Java SE 9, Oracle Corp is going to introduce a new Multi-Resolution Image API.
Important interface in this API is MultiResolutionImage . It is available in
java.awt.image package.

MultiResolutionImage encapsulates a set of images with different Height and


Widths (that is different resolutions) and allows us to query them with our
requirements.

 Miscellaneous Java 9 Features


In this section, I will just list out some miscellaneous Java SE 9 New Features. I’m
NOT saying these are less important features. They are also important and useful
to understand them very well with some useful examples.

As of now, I did not get enough information about these features. That’s why I am
going list them here for brief understanding. I will pickup these Features one by
one and add to above section with a brief discussion and example. And final write
a separate tutorial later.

o GC (Garbage Collector) Improvements


o Stack-Walking API
o Filter Incoming Serialization Data
o Deprecate the Applet API
o Indify String Concatenation
o Enhanced Method Handles
o Java Platform Logging API and Service
o Compact Strings
o Parser API for Nashorn
o Javadoc Search
o HTML5 Javadoc

You might also like