If you are a Java Developer then you must be aware of the debut of Java 9 after three years of Java 8.

Upgrade is the change of nature.

This is what Java is doing, Java has always been the first preference of all Application Architects and developers to develop any kind of applications. And to be in the market with the same choice Java has been coming up with the new features in every version. Introducing Java 8 has been the biggest change and made the life easy for all Java developers. You must be aware of the introduction to Java8  features and enhancements. If not then please find here.

Let’s talk about a major release Java 9  formally, Java Platform Standard Edition version 9—is finally here, and its Java Development Kit (JDK) is available for developers to download.

Do you want to start with JDK 9, Download below from official site

Oracle has posted the Java SE 9 JDK and documentation for download by developers.

Before starting to work on JDK 9, Read below more and update your self with JAVA 9 features.

Java 8 has been described as the major release of lambdas, streams and API changes, then Java 9 is all about Jigsaw, Jshell, and a collection of under the hood and API updates.

 

Let’s see the features introduced in Java 9 listed below.
  1. Java + REPL (Read- Eval -Print -Loop) =JShell
  2. Factory Methods for Immutable List, Set, Map, and Map.Entry
  3. Private methods in Interfaces
  4. Java 9 Module System
  5. Process API Improvements
  6. Try With Resources Improvement
  7. CompletableFuture API Improvements
  8. Reactive Streams
  9. Diamond Operator for Anonymous Inner Class
  10. Optional Class Improvements
  11. Stream API Improvements
  12. Enhanced @Deprecated annotation
  13. HTTP 2 Client
  14. Multi-Resolution Image API
  15. Improvements in Garbage Collection
  16. Introduction to Stack Walking API
  17. Filter Incoming Serialization Data
  18. Deprecate the Applet API
  19. Indify String Concatenation
  20. Enhanced Method Handles
  21. Java Platform Logging API and Service
  22. Compact Strings
  23. Parser API for Nashorn
  24. Javadoc Search
  25. HTML5 Javadoc

 

   1.Java + REPL (Read- Eval -Print -Loop) =JShell

REPL might be a new term for you all, this means if you want to run a few lines of Java on their own you won’t have to wrap it all in a separate project or method. This feature was developed under the Project Kulia.

Developers can get feedback on programs before compilation just by entering some lines of code. It means that you if want to test your logic this will help you.

JShell is an interactive command-line interface for evaluating declarations, statements, and expressions of the Java programming language. This will be an advantage for someone who wants to learn java and practice on All API’s otherwise we used to create a class and need a main method for their execution.

 

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

Factory methods are introduced to create an immutable or unmodifiable instance of Collections. Earlier we used to write a lot of boilerplate code to create an instance of any Collection Object like List, Set and Map.

In Java 8 or before release version we used to use utility methods in Collections class.

  •  To create an unmodifiable collection we use below code:
           Collections.unmodifiableCollection(Collection <? extends T> c)
  • To create an unmodifiable List we use below code:
          Collections.unmodifiableList(List <? extends T> list)
  • To create an unmodifiable Map we use below code:
          Collections.unmodifiableMap(Map<? extends K,? extends V> m)
  • To create an unmodifiable Set we use below code:
          Collections.unmodifiableSet(Set<? extends T> s)


Above approach is very tedious and verbose. To overcome these In Java 9 approach has been changed as below to create an empty and non-empty immutable collection.

List list = List.of(); //this will create an empty list

List list2 = List.of("a","b","c"); // this will create a non-empty


Set set = Set.of(); //this will create an empty set

Set set2 = Set.of("a","b","c"); // this will create a non-empty set


Map map = Map.of(); //this will create an empty map

Map map2= Map.of(1,"a",2,"b",3,"c"); // this will create a non-empty map


 3. Private methods in Interfaces

In Java 8 we got the default and static methods in Interface. Now In Java 9, we have private methods in Interface.

We can have private and private static method in Interface. These private methods can be called from default method or any public method of Interface i.e to share common code between non-abstract methods.

public Interface ProductService {
  
   private String addProduct(Product product){
   //write your own implementation
    }

   private static String addLiveProduct(Product product){
    //write your own implementation
    }
    default void checkAfterUpdate(Product product){
   // addProduct(product);
    }
}

     4. Java 9 Module System(Pigsaw Project)

Modularity – in the form of the Java Platform Module System – divides the JDK into a set of modules for combining at run, compile or build time. Modularity has been called a transitive change, enabling understanding of dependencies across modules.

Whenever we develop large applications or maintain a library, There are some problems, with the increase of the code base, the chance to create complicated code with tangled dependencies increase. It is hard to truly encapsulate code as every public class becomes part of your public API and there is no clear notion of explicit dependencies between different parts of the system.

To resolve these issues Project Jigsaw introduces the concept of modularity; support for creating modules in Java 9 and then apply the same to the JDK; that is, modularize the JDK.

There is a lot of advantage of modularity:

  • Strong encapsulation: The modules can access only those parts of the module that have been made available for use. So the public classes in a package are not public unless the package is explicitly exported in the module info file.
  • Clear dependencies: Modules must declare which other modules they would be using via the requires clause.
  • Combining the modules to create a smaller runtime, which can be easily scaled to smaller computing devices.
  • Reliable: Applications are more reliable by eliminating the run-time error. Example: we have experienced application giving the run-time error due to missing classes, resulting in ClassNotFoundException.

The project was targeted to release in Java 8 but later got delayed and added in Java 9.

There are various JEP’s which are part of this project which provides various features as follows.

  1. JEP 200 -Modular JDK:
  2. JEP 201 – Modular Java Source Code
  3. JEP 220 – Modular Run-time Images
  4. JEP 260 – Encapsulate Java Internal APIs
  5. JEP 261 – Java Platform Module System
  6. JEP 282- jlink, the java linker

 

  1. Modular JDK: This applies the Java platform module system to modularize the JDK into a set of modules that can be combined at compile time, build time and run-time.
  2. Modular Java Source Code: This modularizes the JDK source code into modules and enhances the build tools to compile the modules.
  3. Modular Run-time Images: This restructures the JDK and JRE runtime images to accommodate modules and to improve performance, security, and maintainability.
  4. Encapsulate Java Internal APIs: Encapsulate most of the JDK’s internal APIs by default so that they are inaccessible at compile time and prepare for a future release in which they will be inaccessible at run-time. Ensures that critical widely used internal APIs are not encapsulated. So that they remain accessible until supported replacements exist for all or most of their functionality.
  5. Java Platform Module System: This implements the module system Java Specification by changing the Java programming language, JVM, and other standard APIs.
  6. jLink, java Linker: This allows packaging modules and their dependencies into smaller run times.

If you have not understood above then in simple few lines we are trying to make you understand.

Before Java 9 we were using monolithic Jars to develop Java Based applications. This architecture has a lot of drawback and limitations. To avoid these limitations Java 9 came up with modules system.

We can use JDK Modules and also we can create our own modules as shown in simple examples:

module com.foo.bar{ }
Here we are using 'module' to create a simple module. Each module has name, package and related code

    5. Process API Improvements & Updates

Java has improved its process API in Java 9 that helps to manage and control the operating system processes. They have added a couple of new classes and method to manage the operating system process.

Two  new interfaces in Process API has been added:

  • java.lang.ProcessHandle
  • java.lang.ProcessHandle.Info

With the new improvements and updates, following features are enabled in Process API.

  • we can get the process id (PID) of the current process in JVM
  • we can fetch more info such as PID, name and resource usage by  enumerating the process
  • Managing the process trees
  • Managing the subprocesses

 

Example of Process API :
  ProcessHandle currentProcess = ProcessHandle.current();//current() is a static method in ProcessHandle which will return currentProcess
  System.out.println("Current Process Id: " +currentProcess.getPid());//getPid() is a method used to get the current process Id. 
  System.out.println("Current Process Info: " +currentProcess.info());//get the information about the process
   
  //The current method return an object of Process which is running currently in JVM.
  // The Info Subclass provides details about the process.
   ProcessHandle.Info infoProcess = currentProcess.info();
   Optional<String[]> args = infoProcess.arguments();
   Optional<String> cmd = infoProcess.commandLine();
   Optional<Instant> startTime= infoProcess.startInstant();
   Optional<Duration> cpuUsage = infoProcess.totalCpuDuration();

   //Destroying the process
   //We can stop the all running child process using the destroy method
    childProcess = ProcessHandle.current().children();
    //Iterate using forEach loop
     childProcess.forEach(processHandle ->{
       assertTrue(processHandle .getPid(),processHandle.destroy());
      })

 

      6. Try With Resources Improvement

 

There has been a lot of enhancement in Exception Handling construct: Try-With-Resources to manage the resources automatically.

Java introduced the try-with-resource concept in Java 7 that helps to close resource automatically after being used.

Earlier we used to close the resources like files, connection, network in the finally block, After Java 7  we don’t need to close resources explicitly, try-with-resources close that automatically by using the AutoClosable interface.

Let’s see the Java 7 and Java 9 implementation with an example.

Java 7 Examples:

    BufferedReader buffer =new BufferedReader(new FileReader("sample.txt"));
    try(BuffredReader buffer2 =buffer1){
     //use buffer2 to implement   
 }

 

Java 9 Examples:

 BufferedReader buffer =new BufferedReader(new FileReader("sample.txt"));
 try(buffer1){
 //use buffer2 to implement 
 }


 

In Java 7, try-with-resources syntax required variables to be declared for each resource being managed by the statement

In Java 9, if the resource is referenced by a final or effectively final variable, a try-with-resources statement can manage without a new variable being declared.

 

  7. CompletableFuture API Improvements

In Java 8 CompletableFuture API was introduced as a Java 8 Concurrency API improvement.

The Future interface was added in Java 5 to serve as a result of an asynchronous computation, but it did not have any methods to combine these computations or handle possible errors.

Along with the Future interface, it also implemented the CompleteStage interface. This interface defines the contract for an asynchronous computation step that can be combined with other steps.

CompletableFuture is at the same time a building block and a framework with about 50 different methods for composing, combining, executing asynchronous computation steps and handling errors.

In Java 9 They have added support for some delays and timeouts, some utility method and subclassing.

Executor executor = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);

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

 

 

  8. Reactive Streams

Reactive Programming has become very popular in the current market as we have different languages offering beautiful benefits like Scala, Play, Akka.

As part of Concurrency API updates, Java 9 introduced a new class java.util.concurrent.Flow that provides interfaces that supports the Reactive Streams Publish-Subscribe Framework. These interface support interoperability across a number of asynchronous systems running on JVMs.

Reactive Streams solves the pain of back-pressure.The build-up of data that happens when the incoming tasks rate is higher than the application’s ability to process them, which result in a buffer of unhandled data.

The publish-subscribe framework enables developers to build components that can asynchronously consume a live stream of data by setting up publishers that produces the data and subscribers that consume the data via subscription, which manages them. The five new interfaces are as follows:

  • java.util.concurrent.Flow: This is the main final class which cannot be extended of Flow API.
  • java.util.concurrent.Flow.Publisher: This is a functional interface which has subscribe method is implemented by all publisher class to receive a message.
  • java.util.concurrent.Flow.Subscriber: This interface is implemented by all subscriber and it has following methods executed in sequential order.
    -> onSubscribe() -> onNext() -> onError() -> onComplete()
  • java.util.concurrent.Flow.Subscription: This is used to create asynchronous non-blocking link between publisher and subscriber.
  • java.util.concurrent.Flow.Processor(which acts as both Publisher and Subscriber): This interface extends both the Publisher and Subscriber, this is used to transform the message between publisher and subscriber.

 

   
 9.  Diamond Operator for Anonymous Inner Class

Diamond operator concept was first introduced in Java 7 to avoid the boilerplate code and improve the readability.
In Java 8, some limitations were found which was improved and fixed in Java 9. In Java 7 It was not possible to use diamond operator with anonymous class.
Now we can use the diamond operator in conjunction with the anonymous inner class.

ProductClass<ProductLive> productClass = new ProductClass<>(){
 //anonymous inner class
 };
 
 ProductClass<? extends ProductList > productClass =new ProductClass<>(){
 //anonymous inner class
 }; 
 
 ProductClass<?> productClass = new ProductClass<>(){
 // anonymous inner class
 };

You can read more about this features here on Diamond Operator in Java 9 | Enhancements You Must Know

 

  10. Optional Class Improvements

Optional Class was introduced in Java 8 under java.util.Optional package.
In Java 9 some modifications and additions happened in Optional class with the method: stream()
If a value is present in the given Optional object, this stream() method returns a sequential Stream with that value otherwise it returns an Empty Stream.

List<String> listOfString = listOfOptionals.stream()
.flatMap(Optional:stream)
.collect(Collectors.toList());

 11. Stream API Improvements

 

When we talk about teh Stream API, it is the games changer feature that was introduced in Java 8 which entirely made easy the life of all Java developers. Thanks to Java 8 evolution with this features and along with the addition of new methods in
Java 9 It has become more strong and taken java to strong side on developers community.
Now we will be able to create Stream from Optional.
Along with that, there are new methods introduced in the Stream interface which are static and default methods:
-> iterate {static method}: it is the replacement of for loop using streams. It takes the initial value of the stream, the condition that defines when to stop
iterating and the step function to produce the next element.
There are three arguments to this method.
-> first argument: initializing the value, the returned stream starts with the element 1
-> second argument: the predicate, the iteration continues until this given predicate returns false.
-> third arguments: updates the value of the previous iteration.

Stream.iterate(2, num -> num< 8, num -> num+1).forEach(num -> System.out.println(num))
2,3,4,5,6,7

-> dropWhile {default method}: It discards the first items of the stream until a condition is met.

Stream<Integer> str =Stream.of(1,5,10,20,30,50);
str.dropWhile(num -> num <26).forEach(num -> System.out.println(num))
Output: 30,50

Note: When a stream is unordered, the dropWhile() drops all the elements until the given predicate fails, this method does not check further elements of the stream once the predicate fails.
-> takeWhile {default method} :
This method processed the items until the condition is met.when predicate fails, it drops the elements and all the elements that come after that element in the stream.

Stream<Integer> str =Stream.of(1,5,10,20,30,50);
str.takeWhile(num -> num <26).forEach(num -> System.out.println(num));
Output: 1,5,10,20

-> ofNullable {static method}: As the name only suggests that it is related to some null values yes it is used to avoid the NullPointerException.
This method will return empty the stream when a stream is null.

 

   
 12. Enhanced @Deprecated annotation

@Deprecated annotation is a marker interface which is used to mark on class, field, method, interface, constructor, enum etc.
In Java 9 they have added two new methods/attributes which are used to provide more information:
-> forRemoval: it represents that the annotated element is subject to removal in the future release.
-> since: it represents the version in which the annotated element became deprecated

We use the @deprecated Javadoc tag to explain the reason for deprecating a program element.

 

   13. HTTP 2 Client

HTTP/1.1 client was first introduced in 1997 release of Java. After that there has been a lot of change in the process and connecting to client system has been stagnant with HTTP/1.1 version, we faced a lot of issues related to supporting, performance and works only in blocking mode means that – one thread per request/response pair which increases the latency and loading times.

Now HTTP/2 protocol has been introduced under java.net.http package. It supports both HTTP/2 protocol and WebSocket handshake, with the performance that should be comparable with the Apache HttpClient, Netty, and Jetty.
The main difference between the HTTP/1.1 and HTTP/2 is in the framing of data that is transported between client and server.
HTTP/1.1 relies on the request/response cycle.
HTTP/2 allows the server to “push” data. It can send back more data than the client requested. This allows it to prioritize and send the data crucial for loading the webpage first.

Java 9 has introduced three major class in HTTP/2 Client.
-> HttpClient:
-> HttpRequest:
-> HttpResponse:
The new version aims to reduce the latency, to thus allow for faster loading of web pages. This is achieved through various techniques:
-> Header compression
-> Server-push
-> Pipelining
-> Multiplexing of multiple HTTP requests across a TCP connection.

Let’s see some implementation:

HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest httpRequest = HttpRequest.newBuilder().uri(new URI("//amitclive.com/")).GET().build();
HttpResponse<String> httpResponse = httpClient.send(httpRequest,HttpResponse.BodyHandler.asString());
System.out.println(httpResponse.body());

 

New API also supports for the Async HTTP request using httpClient.sendAsync() method .It returns CompletableFuture Object which can be used o determine the request has been completed or not. It also provides the access to the HttpResponse once the request is completed.

 

14. Multi-Resolution Image API

In Java 9 A new interface MultiResolutionImage is introduced under the package java.awt.image that encapsulates set of images with the different resolutions into a single object, a set of images with different height and widths and allows us to query based on our requirements.
The class java.awt.image.BaseMultiResolutionImage provides the basic implementations:

MultiResolutionImage mrImage = new BaseMultiResolutionImage(baseIndex , resolutionVariants);
Image testImage = mrImage.getResolutionVariant(32,32);
assertSame("Image should be same", testImage , mrImage[2]);

 

 

  15. Garbage Collection Improvements:

Garbage collection is one of the most important features of Java which makes our application light free from unused objects.There are four garbage collector in Java:
-> Serial GC: optimized for memory footprint
-> Parallel GC: optimized for throughput
-> Concurrent Mark Sweep: optimized for Latency
-> G1 Collector: optimized for Throughput/Latency Balance

 

Let’s know about G1 Collector.

The goal of G1 Collector is throughput and low latency
The default pause target for G1 is 200 milliseconds.
-> Higher pause goal -> more throughput, higher latency
-> Lower pause goal -> less throughput , lower latency
G1 divides the heaps into multiple regions and keep track of live objects without stopping java applications.
G1 then collects a few regions at a time.
Fewer objects to collect -> shorter pause
More information- more control over the pause

Prior to Java 9, the default garbage collector was the parallel/Throughput collector But now G1 is the default garbage collector which was introduced in Java 7.

It is a multithreaded GC. It works along with the application threads much like concurrent mark sweeps as the algorithm is the same. First, it concurrently identifies all the referenced objects in the heap and marks them correspondingly. Then it collects the emptiest region first, releasing a lot of free space. That’s why it is called Garbage-First.What makes G1GC different is that it splits the heaps into sets of equal sized ones

Over the long period of times, the application that used Parallel garbage collector tend to spend overall less time in garbage collection but can potentially have some longtime pause. This cause latency, affecting the responsiveness of the application.

G1 improvements:
-> String de-duplications
-> Class unloading after concurrent cycle
-> Eager reclamation of homongous objects
-> Adaptive start of concurrent cycle
-> More effective pause

 

 

16. Stack Walking API

StackWalking API is introduced in Java 9 to have a clear picture on the stack trace element easy filtering of, and lazy access to, the information in stack traces.

Till Java 8, StackTrace Element represnts a stack frame .

To get complete stack, we had to use Thread.getStackTrace() and Throwable.getStakcTrace().
It returned an array of StackTraceElement which we can iterate to get the required information.
StackWalker is a class introduced in Java 9 which provides easy and efficient stack walking using the sequential stream of stack frames for the current thread. The StackWalker class which give access to the stack is very efficient because it evaluates the stack frames lazily.

 

StackWalker.getInstance().forEach(System.out:println);The forEach method will forward all the unfiltered frames to the specified Consumer<StackFrame> callback.
 
<T> T walk(Function<Stream<StackWalker.StackFrame>, T> function): The walk method takes a function that gets a stream of stack frames and returns the result.

 

  17.  Filer Incoming Serialization Data

Serialization Filtering
Serialization Filtering is the minimum that Oracle could provide in order to stop being blamed for not doing anything about the critical Deserialization attacks. It is a first step in the right direction but it does not completely solve the problem and is not suitable for enterprise production environments.

In order to improve the security and robustness of an application, all the incoming stream of object-serialization should be filtered which was missing earlier.
Oracle introduced this mechanism into the JVM to provide a means to adhere to some of these security guidelines.
If enabled and properly configured, it will allow serialized data to be validated before deserialization is performed.
This validation is performed by a new filter that is essentially based on a white/black listing approach.
This mechanism supports three types of filters.
-> Process-wide Filter :
A process-wide filter is configured via a system property or a configuration file. The system property, if supplied, supersedes the security property value.

System property jdk.serialFilter
Security property jdk.serialFilter in conf/security/java.properties

-> Specific Filters :
Developers can implement custom filters using the new ObjectInputFilter class. These filters are implemented in the source code
of the application and override the behavior of the Global Filter. It requires development effort to implement these filters.

-> Built-in Filters:
There are two built-in filters that are specific for the RMI Registry and the Distributed Garbage Collection.
These built-in filters implement pre-configured whitelists of classes and limits that are typical for the RMI Registry and  DGC use cases. The pre-configured filter pattern is the following:

 
java.rmi.server.ObjID;
java.rmi.server.UID;
java.rmi.dgc.VMID;
java.rmi.dgc.Lease;
maxdepth=5;
maxarray=10000

 

  18.   Deprecate the Applet API

 

In an earlier time we used to have client applications based on applets But nowadays browser world has changed completely and security has been a major issue for all major browser vendors. Browser vendors have now removed the support for java plugins. Once the plugin is removed then there is no use of Applet API as it will not work.
Add the @Deprecated(since=”9″) annotation to the following classes:

java.applet.AppletStub
java.applet.Applet
java.applet.AudioClip
java.applet.AppletContext
javax.swing.JApplet

They are not going to remove the Applet API in the next major release, hence they will not specify forRemoval = true in these annotations.
If at some later point they propose to remove this API then they will add forRemoval = true to these annotations at least one major release in advance.

 

 19.  Indify String Concatenation

In Java 9, the way of the concatenation of String has completely changed on the compiler level as compared to the previous level.
Earlier whenever we used to concat two string, internally implementation was taken from StringBuilder append method.

Let’s see this program:

String result = abc + "-" + 123 + "-" + efg;
System.out.println(result);

If we compile that with JDK 8 or earlier and then use javap -c Example to see the bytecode, we see something like this:

 

 

Code:
0: new #2 // class java/lang/StringBuilder
3: dup
4: invokespecial #3 // Method java/lang/StringBuilder."<init>":()V
7: aload_0
8: iconst_0
9: aaload
10: invokevirtual #4 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
 

 

As you can see, it creates a StringBuilder and uses append. This is famous fairly inefficient as the default capacity of the built-in buffer in StringBuilder is only 16 chars, and there’s no way for the compiler to know to allocate more in advance, so it ends up having to reallocate.
It’s also a bunch of method calls. (Note that the JVM can sometimes detect and rewrite these patterns of calls to make them more efficient, though.)

Let’s look at what Java 9 generates:

 

Code:
0: aload_0
1: iconst_0
2: aaload
3: aload_0
4: iconst_1
5: aaload
6: aload_0
7: iconst_2
8: aaload
9: invokedynamic #2, 0 // InvokeDynamic #0:makeConcatWithConstants:(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
14: astore_1
15: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
18: aload_1
19: invokevirtual #4 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
22: return
 
 
It makes a single call to makeConcatWithConstants from StringConcatFactory, which says this in its Javadoc:
 
Methods to facilitate the creation of String concatenation methods, that can be used to efficiently concatenate a known number of arguments of known types, possibly after type adaptation and partial evaluation of arguments. These methods are typically used as bootstrap methods for invokedynamic call sites, to support the string concatenation feature of the Java Programming Language.

 

20. Enhanced Method Handles

 

In Java 7 a new API was introduced under java.lang.invoke package i.e MethodHandles.
As per the documentation, we see below definition for this as:
A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values.

In Java 9 the focus was on these three parts:

1. Lookup functions: allows classes to lookup from different context explained below.

2. Argument Handling: improves the argument folding, argument collecting and argument spreading functionalities.

3. Additional Combinations: adding loops (loopwhileLoop, doWhileLoop…) and a better exception handling support with the tryFinally

MethodHandles are immutable and have no visible states.
For creating and using a method handles four steps are required.
-> Creating the lookup
-> Creating the method type
-> Finding the method handle
-> Invoking the method handle

The class java.lang.invoke.MethodHandles is enhanced in Java 9 to include more static methods for creating different kinds of method handles.

Let’s create the lookup that provides access to public methods:

MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();

However, in case we want to have access also to private and protected methods, we can use, instead, the lookup() method:

 

MethodHandles.Lookup lookup = MethodHandles.lookup();

In the same way as MethodHandle, even the instances of a MethodType are immutable.

Let’s see how it’s possible to define a MethodType that specifies a java.util.List class as return type and an Object array as input type:

MethodType mt = MethodType.methodType(List.class, Object[].class);

In case the method returns a primitive type or void as its return type, we will use the class representing those types
(void.class, int.class …).

Let’s define a MethodType that returns an int value and accepts an Object:

 

MethodType mt = MethodType.methodType(int.class, Object.class);

 

Method Handle for Methods

MethodType mt = MethodType.methodType(String.class, String.class);
MethodHandle concatMH = publicLookup.findVirtual(String.class, "concat", mt);

Method Handle for Static Methods

MethodType mt = MethodType.methodType(List.class, Object[].class);
 
MethodHandle asListMH = publicLookup.findStatic(Arrays.class, "asList", mt);

 

Method Handle for Constructors

MethodType mt = MethodType.methodType(void.class, String.class);
 
MethodHandle newIntegerMH = publicLookup.findConstructor(Integer.class, mt);

 

Method Handle for Fields

public class Book {
 
String id;
String title;
 
// constructor
 
}

 

Having as precondition a direct access visibility between the method handle and the declared property, we can create a method handle that behaves as a getter:

MethodHandle getTitleMH = lookup.findGetter(Book.class, "title", String.class);

 

Method Handle for Private Methods

private String formatBook() {
return id + " > " + title;
}

Now we can create a method handle that behaves exactly as the formatBook() method:

Method formatBookMethod = Book.class.getDeclaredMethod("formatBook");
formatBookMethod.setAccessible(true);
 
MethodHandle formatBookMH = lookup.unreflect(formatBookMethod);

Invoking a Method Handle

MethodType mt = MethodType.methodType(String.class, char.class, char.class);
MethodHandle replaceMH = publicLookup.findVirtual(String.class, "replace", mt);
 
String output = (String) replaceMH.invoke("jovo", Character.valueOf('o'), 'a');
 
assertEquals("java", output);

 

 

 

 

21.  Java Platform Logging API and Service:

 

In Java 9 the JVM logging platform has come up with some new improved features through the new logging API.
It lets us specify the logging framework of our own choice. This is a common logging system for the all components of JVM not for Application classes.
There are few things to be kept in mind about these API.
-> This API is meant to be used by the classes in the JDK, not by application classes.
-> For our application we will continue using our customized logging framework.
-> We cannot configure the logger programmatically.

The API consist of the following:
-> A service interface, java.lang.System.LoggerFinder, which is an abstract static class
-> An interface, java.lang.Logger, which provides the logging API.
-> An overloaded method getLogger() in the java.lang.System class which returns a logger instance.
The logging framework defines a set of tags, for example, gc, compiler, threads etc. We can use the command line parameter
-Xlog to turn on logging during startup.

 

 22.  Compact Strings:

Earlier String Class was internally represented by char[] where 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.
After all these analysis they replaced the internal implementation to byte[] from char[].

Let’s see the String implementation Before Java 9 :

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
 
//The value is used for character storage.
private final char value[];
 
}

 

 

After Java 9, the String implementation are :

public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
 
/** The value is used for character storage. */
private final byte[] value;

 

23.  Parser API for Nashorn:

Nashorn API was introduced in Java 8 which was an effort to implement a high performance but lightweight javascript runtime in Java.
Project Nashorn was charged with enabling the embedding of javascript in Java applications.
In Java 9 the API :
-> Provides interface classes to represent Nashorn syntax-tree nodes.
-> Provide a factory to create a configured parser instance, with configuration done by passing Nashorn command-line options via an API.

-> Provide a visitor-pattern API to visit AST nodes.

-> Provide sample/test programs to use the API.

 

 24.  Javadoc Search:

The Java 9 Javadoc tool documentation states that the @index tag is used to specify an indexed “search term or a phrase” that can be searched for in Java 9’s new Javadoc Search feature.

Add a search box to API documentation generated by the standard doclet that can be used to search for program elements and tagged words and phrases within the documentation. The search box appears in the header of all pages generated by the standard doclet.

 

25. HTML5 Javadoc

 

In Java 8 and earlier, Javadocs are generated using HTML 4.01. While it’ll continue to be the default, with Java 9 comes the option to have your Javadocs generated in the much more modern HTML5.

Javadoc is a tool for generating API documentation. It generates the documentation in HTML format. JEP 224 enhances the javadoc tool to generate HTML5 markup. It currently generates pages in HTML 4.01.

The easiest way to learn about javadoc and experience the benefits to your documentation is to use it. Download the Java 9 Early Access Release. You can check the Javadoc version is “9” by running:

javadoc -J-version

 

 

This blog is only about the introduction to Java 9 features, I will go in details and explain it, So stay tuned.

 

Amit is a software developer by profession. He is passionate about all the technologies which can be used to build an application like java related technologies and many more and loves to implement it his career or for knowledge purpose and share his experience with you all. To know more see the About me profile.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.