Sitemap
Shehrazkhan

Shehrazkhan

  1. Java 9 Module System
  2. Modules

3. Private Interface Methods

4. Try With Resource Enhancement

5. Anonymous Inner Classes Improvement

6. @SafeVarargs Annotation

7. Collection Factory Methods

8. Stream API Improvement

1. Java 9 Modules System

Java Module System is a major change in Java 9 version. Java added this feature to collect Java packages and code into a single unit called module.

In earlier versions of Java, there was no concept of module to create modular Java applications, that why size of application increased and difficult to move around. Even JDK itself was too heavy in size, in Java 8, rt.jar file size is around 64MB. To deal with situation, Java 9 restructured JDK into set of modules so that we can use only required module for our project. Apart from JDK, Java also allows us to create our own modules so that we can develop module-based application.

The module system includes various tools and options that are given below.

i. Includes various options to the Java tools javac, jlink and java where we can specify module paths that locates to the location of module.

ii. Modular JAR file is introduced. This JAR contains module-info.class file in its root folder.

iii. JMOD format is introduced, which is a packaging format similar to JAR except it can include native code and configuration files.

iv. The JDK and JRE both are reconstructed to accommodate modules. It improves performance, security and maintainability.

v. Java defines a new URI scheme for naming modules, classes and resources.

2. Modules

Module is a collection of Java programs or software’s. To describe a module, a Java file module-info.java is required.

This file also known as module descriptor and defines the following

o Module name

o What does it export

o What does it require

Module Name

It is a name of module and should follow the reverse-domain-pattern. Like we name packages, e.g., com.javapoint.

How to create Java module

Creating Java module required the following steps.

o Create a directory structure

o Create a module declarator

o Java source code

Create a Directory Structure

To create module, it is recommended to follow given directory structure, it is same as reverse-domain-pattern, we do to create packages / project-structure in Java.

Note: The name of the directory containing a module’s sources should be equal to the name of the module, e.g. com.javapoint.

Create a module declarator

Create a file module-info.java, inside this file, declare a module by using module identifier and provide module name same as the directory name that contains it. In our case, our directory name is com.javatpoint.

module com.javatpoint {

}
Leave module body empty, if it does not have any module dependency. Save this file inside src/com.javatpoint with module-info.java name.

Java Source Code

Now, create a Java file to compile and execute module. In our example, we have a Hello.java file that contains the following code.

class Hello 
{
public static void main(String[] args)
{
System.out.println("Hello from the Java module");
}
}

Save this file inside src/com.javatpoint/com/javatpoint/ with Hello.java name

Compile Java Module

To compile the module, use the following command.

javac -d mods — module-source-path src/ — module com.javatpoint
After compiling, it will create a new directory that contains the following structure.

Now, we have a compiled module that can be just run.

Run Module

To run the compiled module, use the following command.
java — module-path mods/ — module com.javatpoint/com.javatpoint.Hello Output: Hello from the Java module

Well, we have successfully created, compiled and executed Java module.

Look inside compiled Module Descriptor

To see the compiled module descriptor, use the following command.

javap mods/com.javatpoint/module-info.class
This command will show the following code to the console.

Compiled from "module-info.java"
module com.javatpoint {
requires java.base;
}

See, we created an empty module but it contains a java.base module. Why? Because all Java modules are linked to java.base module and it is default module.

3. Private Interface Methods

In Java 9, we can create private methods inside an interface. Interface allows us to declare private methods that help to share common code between non-abstract methods.

Before Java 9, creating private methods inside an interface cause a compile time error. The following example is compiled using Java 8 compiler and throws a compile time error.

Note: To implement private interface methods, compile source code using Java 9 or higher versions only.

Now, lets execute the above code by using Java 9. See the output, it executes fine.

4. Try With Resource Enhancement

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

Get Shehrazkhan’s stories in your inbox

Join Medium for free to get updates from this writer.

In other words, we can say that we don’t need to close resources (file, connection, network etc.) explicitly, try-with-resource close that automatically by using AutoClosable interface.

In Java 7, try-with-resources has a limitation that requires resource to declare locally within its block.

Example Java 7 Resource Declared within resource block

This code executes fine with Java 7 and even with Java 9 because Java maintains its legacy.

But the below program would not work with Java 7 because we can’t put resource declared outside the try-with-resource.

Java 7 Resource declared outside the resource block If we do like the following code in Java 7, compiler generates an error message.

To deal with this error, try-with-resource is improved in Java 9 and now we can use reference of the resource that is not declared locally.

In this case, if we execute the above program using Java 9 compiler, it will execute nicely without any compile error.

5. Anonymous Inner Classes Improvement

Java 9 introduced a new feature that allows us to use diamond operator with anonymous classes. Using the diamond with anonymous classes was not allowed in Java 7.

In Java 9, as long as the inferred type is denotable, we can use the diamond operator when we create an anonymous inner class.

Data types that can be written in Java program like int, String etc are called denotable types. Java 9 compiler is enough smart and now can infer type.

Note: This feature is included to Java 9, to add type inference in anonymous inner classes.

Let’s see an example, in which we are using diamond operator with inner class without specifying type.

Although we can specify type in diamond operator explicitly and compiler does not produce any error message. See, the following example, type is specified explicitly.

ABCD<String> a = new ABCD<String>() // diamond operator is not empty
And we get the same result.
Output:
Java9

6. @SafeVarargs Annotation

It is an annotation which applies on a method or constructor that takes varargs parameters. It is used to ensure that the method does not perform unsafe operations on its varargs parameters.

It was included in Java7 and can only be applied on
o Final methods
o Static methods
o Constructors

From Java 9, it can also be used with private instance methods. Note: The @SafeVarargs annotation can be applied only to methods that cannot be overridden. Applying to the other methods will throw a compile time error. Let’s see some examples, in first example, we are not using @SafeVarargs annotation and compiling code

This is a compiler generated warning regarding unsafe varargs type.
To avoid it, we should use @SaveVarargs notation to the method, as we did in the following example.

Press enter or click to view image in full size

Note: To apply @SaveVarargs annotation on private instance methods, compile code using Java 9 or higher versions only.

7. Factory Methods

Java 9 Collection library includes static factory methods for List, Set and Map interface. These methods are useful to create small number of collection.
Suppose, if we want to create a list of 5 elements, we need to write the following code.

Factory Methods for Collection

Factory methods are special type of static methods that are used to create unmodifiable instances of collections. It means we can use these methods to create list, set and map of small number of elements.
It is unmodifiable, so adding new element will throw java.lang.UnsupportedOperationException
Each interface has its own factory methods, we are listing all the methods in the following tables.

Set Interface

Java Set interface provides a Set.of() static factory method which is used to create immutable set. The set instance created by this method has the following characteristics.
o It is immutable
o No null elements
o It is serializable if all elements are serializable.
o No duplicate elements.
o The iteration order of set elements is unspecified and is subject to change.

Press enter or click to view image in full size

Map Interface Factory Methods

In Java 9, Map includes Map.of() and Map.ofEntries() static factory methods that provide a convenient way to create immutable maps.
Map created by these methods has the following characteristics.
o It is immutable o It does not allow null keys and values
o It is serializable if all keys and values are serializable
o It rejects duplicate keys at creation time
o The iteration order of mappings is unspecified and is subject to change.

Press enter or click to view image in full size

Map Interface ofEntries() Method Example

In Java 9, apart from static Map.of() methods, Map interface includes one more static method Map.ofEntries(). This method is used to create a map of Map.Entry instances.

Press enter or click to view image in full size
Press enter or click to view image in full size

8. Stream API Improvement

In Java 9, Stream API has improved and new methods are added to the Stream interface. These methods are tabled below.

Press enter or click to view image in full size

Java Stream takeWhile() Method

Stream takeWhile method takes each element that matches its predicate. It stops when it get unmatched element. It returns a subset of elements that contains all matched elements, other part of stream is discarded.

Example:In this example, we have a list of integers and picks up even values by using takewhile method.

Java Stream dropWhile() Method

Stream dropWhile method returns result on the basis of order of stream elements.

Ordered stream: It returns a stream that contains elements after dropping the elements that match the given predicate.
Unordered stream: It returns a stream that contains remaining elements of this stream after dropping a subset of elements that match the given predicate.

Java 9 Stream ofNullable Method

Stream ofNullable method returns a sequential stream that contains a single element, if non-null. Otherwise, it returns an empty stream.It helps to handle null stream and NullPointerException.

Java Stream Iterate Method

A new overloaded method iterate is added to the Java 9 stream interface. This method allows us to iterate stream elements till the specified condition.

It takes three arguments, seed, hasNext and next.

--