What are the new features of java-9?
On 21 September 2017, Oracle released a new version of Java as Java-9. It was a revolutionary release of Java for the software development platform. Following are the new features of java-9.
1. Modular System (Project Jigsaw):
- This feature is added to collect Java packages and code into a single unit called a module.
- Java 9 restructure the JDK into set of modules so that we can use only the required module for our project. We can also create our modules.
- What is Module?
- A module is a collection of Java programs or softwares.module-info.java is required to describe a module which is known as a module descriptor.
- It describes the module name, what it exports, and what is required.
2. Private Methods in Interface:
- As for java-8 we have default methods in the interface, java-9 introduced private methods now we can also create private methods in an interface. as shown below.
package com.ugtworld;
public class Test {
public static void main(String[] args) {
A a = new B();
a.greet();
}
}
interface A {
void greet();
default void showMessage() {
message();
}
// Only interface A can call this private method.
private void message() {
System.out.print(“this is ugtworld.com”);
}
}
class B implements A {
@Override
public void greet() {
System.out.print(“Welcome user, “);
showMessage();
}
}
public class Test {
public static void main(String[] args) {
A a = new B();
a.greet();
}
}
interface A {
void greet();
default void showMessage() {
message();
}
// Only interface A can call this private method.
private void message() {
System.out.print(“this is ugtworld.com”);
}
}
class B implements A {
@Override
public void greet() {
System.out.print(“Welcome user, “);
showMessage();
}
}
Output:
Welcome user, this is ugtworld.com3. Try-With-Resources:
- In java-7 we have try-with-resources but we need to declare the resource within the same box, resources that are declared outside can not be used in try-with-resources.
- Java-9 enhanced this new feature to use the resources which are declared outside as shown the below example.
package com.ugtworld;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
// make sure we are giving a valid file path.
FileInputStream file = new FileInputStream(
“C:\\Users\\Shwetali\\eclipse-workspace\\Test\\src\\com\\ugtworld\\temp.txt”);
try (file) {
int i;
while ((i = file.read()) != -1) {
System.out.print((char) i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
import java.io.FileInputStream;
import java.io.FileNotFoundException;
public class Test {
public static void main(String[] args) throws FileNotFoundException {
// make sure we are giving a valid file path.
FileInputStream file = new FileInputStream(
“C:\\Users\\Shwetali\\eclipse-workspace\\Test\\src\\com\\ugtworld\\temp.txt”);
try (file) {
int i;
while ((i = file.read()) != -1) {
System.out.print((char) i);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
This is ugtworld file.4. Anonymous Classes (Diamond operator):
- In java-7 we can not use the diamond operator for creating an Anonymous class. java-9 allows to creation of the Anonymous class using the diamond operator as long as the type is denotable.
- As shown in the following example, we can keep the diamond operator empty, and at compile time compiler infer the type automatically.
- If we try to run the code in java-8 we will get the compile time exception like cannot use ‘<>’.
package com.ugtworld;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Employee> list = new ArrayList<>(); // diamond operator is empty
// Adding double as second input type
Employee<String, Double> e1 = new Employee<>() {// diamond operator is empty,
String t;
Double i;
@Override
public void addDetails(String t, Double i) {
this.t = t;
this.i = i;
}
@Override
public void showDetails() {
System.out.println(“Name: ” + t + “, Salary: ” + i );
}
};
e1.addDetails(“CBXS”, 98364.5);
// adding Integer as second input type
Employee<String, Integer> e2 = new Employee<>() {
String t;
Integer i;
@Override
public void addDetails(String t, Integer i) {
this.t = t;
this.i = i;
}
@Override
public void showDetails() {
System.out.println(“Name: ” + t + “, Salary: ” + i );
}
};
e2.addDetails(“DKSC”, 98364);
list.add(e1);
list.add(e2);
list.forEach(e -> e.showDetails());
}
}
interface Employee<T, I> {
void addDetails(T t, I i);
void showDetails();
}
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Employee> list = new ArrayList<>(); // diamond operator is empty
// Adding double as second input type
Employee<String, Double> e1 = new Employee<>() {// diamond operator is empty,
String t;
Double i;
@Override
public void addDetails(String t, Double i) {
this.t = t;
this.i = i;
}
@Override
public void showDetails() {
System.out.println(“Name: ” + t + “, Salary: ” + i );
}
};
e1.addDetails(“CBXS”, 98364.5);
// adding Integer as second input type
Employee<String, Integer> e2 = new Employee<>() {
String t;
Integer i;
@Override
public void addDetails(String t, Integer i) {
this.t = t;
this.i = i;
}
@Override
public void showDetails() {
System.out.println(“Name: ” + t + “, Salary: ” + i );
}
};
e2.addDetails(“DKSC”, 98364);
list.add(e1);
list.add(e2);
list.forEach(e -> e.showDetails());
}
}
interface Employee<T, I> {
void addDetails(T t, I i);
void showDetails();
}
Output:
Name: CBXS, Salary: 98364.5Name: DKSC, Salary: 98364
5. Collection Factory Methods:
- In Java-9 static factory methods for the List, Set and Map interface are included in the Collection library, and use to create a small number of collections.
- As shown in the following example we can create a set, list, or map.
- Note that It rejects duplicate values at creation time.
- Hence If we try to add a duplicate value/key in a set or map we will get an IllegalArgumentException: duplicate element.
- Also if we try to add elements later then it will not allow and throw an java.lang.UnsupportedOperationException.
package com.ugtworld;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
List<String> list = List.of(“ABCD”, “EFGH”, “IJKL”, “MNOP”, “QRST”);
Set<Integer> set = Set.of(1, 4, 3, 5, 7, 2, 9);
Map<Integer, String> map = Map.of(1, “ABCD”, 2, “EFGH”, 3, “MNOP”);
System.out.println(list);
System.out.println(set);
System.out.println(map);
}
}
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Test {
public static void main(String[] args) {
List<String> list = List.of(“ABCD”, “EFGH”, “IJKL”, “MNOP”, “QRST”);
Set<Integer> set = Set.of(1, 4, 3, 5, 7, 2, 9);
Map<Integer, String> map = Map.of(1, “ABCD”, 2, “EFGH”, 3, “MNOP”);
System.out.println(list);
System.out.println(set);
System.out.println(map);
}
}
Output:
[ABCD, EFGH, IJKL, MNOP, QRST][1, 2, 3, 4, 5, 7, 9]
{1=ABCD, 2=EFGH, 3=MNOP}
6. Process API Improvement:
- Java-9 has improved its process API that helps to manage and control operating system processes. New classes and interfaces are added to perform this task.
- Abstract class java.lang.Process and New interfaces ProcessHandle and ProcessHandle.Info are added. Some of the methods examples are as below.
package com.ugtworld;
public class Test {
public static void main(String[] args) {
ProcessHandle processHandle = ProcessHandle.current();
System.out.println(“Process Id: ” + processHandle.pid());
System.out.println(“Is process alive: ” + processHandle.isAlive());
}
}
public class Test {
public static void main(String[] args) {
ProcessHandle processHandle = ProcessHandle.current();
System.out.println(“Process Id: ” + processHandle.pid());
System.out.println(“Is process alive: ” + processHandle.isAlive());
}
}
Output:
Process Id: 12104Is process alive: true
7. Stream API Improvement:
- In java-9 Stream API has improved and new methods are added to the Stream interface.
- New methods are as shown in the example below.
package com.ugtworld;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
/* —- 1. takeWhile(Predicate<? super T> predicate) ——
> This will add the elements while they are less than 5
*/
List<Integer> lessThan5 = list.stream()
.takeWhile(i -> (i < 5))
.collect(Collectors.toList());
System.out.println(“takeWhile: ” + lessThan5);
/* —- 2. dropWhile(Predicate<? super T> predicate) ——
> This will drop the elements while they are less than or equal to 5
*/
List<Integer> greaterThan5 = list.stream()
.dropWhile(i -> (i <= 5))
.collect(Collectors.toList());
System.out.println(“dropWhile: “+ greaterThan5);
/* —- 3. ofNullable(T t)
> It returns a sequential Stream containing a single element, if non-null,
otherwise returns an empty Stream.
> It helps to handle null stream and NullPointerException
*/
Stream<String> val = Stream.ofNullable(“BAGD”);
val.forEach(System.out::println); // this will print BAGD
val = Stream.ofNullable(null);
val.forEach(System.out::println); // This will not print anything
/*
—- 4. iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
> This method allows us to iterate stream elements till the specified condition.
*/
List<Integer> even = Stream.iterate(2, i -> i <= 10, i -> i+2)
.collect(Collectors.toList());
System.out.println(“iterate Example: ” + even);
}
}
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Test {
public static void main(String[] args) {
List<Integer> list = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
/* —- 1. takeWhile(Predicate<? super T> predicate) ——
> This will add the elements while they are less than 5
*/
List<Integer> lessThan5 = list.stream()
.takeWhile(i -> (i < 5))
.collect(Collectors.toList());
System.out.println(“takeWhile: ” + lessThan5);
/* —- 2. dropWhile(Predicate<? super T> predicate) ——
> This will drop the elements while they are less than or equal to 5
*/
List<Integer> greaterThan5 = list.stream()
.dropWhile(i -> (i <= 5))
.collect(Collectors.toList());
System.out.println(“dropWhile: “+ greaterThan5);
/* —- 3. ofNullable(T t)
> It returns a sequential Stream containing a single element, if non-null,
otherwise returns an empty Stream.
> It helps to handle null stream and NullPointerException
*/
Stream<String> val = Stream.ofNullable(“BAGD”);
val.forEach(System.out::println); // this will print BAGD
val = Stream.ofNullable(null);
val.forEach(System.out::println); // This will not print anything
/*
—- 4. iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
> This method allows us to iterate stream elements till the specified condition.
*/
List<Integer> even = Stream.iterate(2, i -> i <= 10, i -> i+2)
.collect(Collectors.toList());
System.out.println(“iterate Example: ” + even);
}
}
Output:
takeWhile: [1, 2, 3, 4]dropWhile: [6, 7, 8, 9, 10]
BAGD
iterate Example: [2, 4, 6, 8, 10
8. @SafeVarargs Annotation:
- we have @SafeVarargs annotation as part of java-7 which can be used on final, static methods and constructors. This annotation is added on the methods which takes varargs as input parameters.
- From java-9 onward we can also add this annotation on private methods as shown in the example below.
package com.ugtworld;
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.addValues(new Integer[]{10,20,30,40});
t.addValues(new Integer[]{1,2,3,4});
}
private void addValues(Integer[] nums) {
List<Integer> list = Arrays.asList(nums);
int sum = list.stream().mapToInt(Integer::valueOf).sum();
System.out.println(“Addition of “+list+” is: ” + sum);
}
}
import java.util.Arrays;
import java.util.List;
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.addValues(new Integer[]{10,20,30,40});
t.addValues(new Integer[]{1,2,3,4});
}
private void addValues(Integer[] nums) {
List<Integer> list = Arrays.asList(nums);
int sum = list.stream().mapToInt(Integer::valueOf).sum();
System.out.println(“Addition of “+list+” is: ” + sum);
}
}
Output:
Addition of [10, 20, 30, 40] is: 100Addition of [1, 2, 3, 4] is: 10
9. New Version-String Scheme:
- This version-string consists of major, minor, security and patch update releases.
10. JShell: The Java Shell (REPL):
- This is an interactive Java Shell tool, which allows us to execute Java code from the shell and get the output immediately.
11. Control Panel:
- This is used to control Java applications that are embedded in browser.