Java 9 New Features With Example
Java 9 was a major release of the Java programming language, and it introduced several new features and improvements. Here are some of the key features, along with detailed code examples:
1. JShell: Java JShell is a new command-line tool that allows developers to run Java code snippets, test ideas, and explore APIs in an interactive way. Here are some examples of how to use JShell:
- Basic usage: To start JShell, simply open a command prompt and type "jshell". This will open the JShell prompt, where you can start typing Java code. For example:
1$ jshell
2jshell> System.out.println("Hello, World!");
3Hello, World!
4
- Variables and types: JShell supports basic variable and type declarations, just like a regular Java program. For example:
1jshell> int x = 5;
2x ==> 5
3jshell> String name = "John";
4name ==> "John"
5
- Expressions and statements: JShell can evaluate expressions and run statements, just like a regular Java program. For example:
1jshell> 2 + 2
2$1 ==> 4
3jshell> if (x > 0) {
4 ...> System.out.println("x is positive");
5 ...> }
6x is positive
7
- Imports: JShell supports importing classes and packages, just like a regular Java program. For example:
1jshell> import java.util.Scanner;
2jshell> Scanner scanner = new Scanner(System.in);
3scanner ==> java.util.Scanner[delimiters=\p{javaWhitespace}+][position=0][match valid=false][need input=false][source closed=false][skipped=false][group separator=\,][decimal separator=\.][positive prefix=][negative prefix=\Q-\E][positive suffix=][negative suffix=][NaN string=\QNaN\E][infinity string=\Q∞\E]
4
- Methods: JShell supports defining and calling methods, just like a regular Java program. For example:
1jshell> int add(int a, int b) { return a + b; }
2| created method add(int,int)
3
4jshell> add(2, 3)
5$2 ==> 5
6
- Saving and loading: JShell allows you to save your session and load it later. For example:
1jshell> /save mySession
2... The file mySession.jsh has been written.
3jshell> /open mySession
4... The file mySession.jsh has been read and executed.
5
These are just a few examples of how to use JShell. For more information and more advanced usage, you can refer to the official JShell documentation.
2. Stream API improvements: Java 9 introduced several new methods to the Stream API, including takeWhile() and dropWhile(). These methods allow developers to filter a stream based on a condition, and can be used to simplify complex filtering operations. Here's an example of how to use takeWhile() to filter a stream of integers:
- takeWhile and dropWhile: These two methods allow developers to filter elements from a stream based on a given predicate. takeWhile will take elements from the stream as long as the predicate is true, and dropWhile will drop elements from the stream as long as the predicate is true. For example:
1List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
2numbers.stream().takeWhile(n -> n < 5).forEach(System.out::println);
3// Output: 1 2 3 4
4numbers.stream().dropWhile(n -> n < 5).forEach(System.out::println);
5// Output: 5 6 7 8 9
6
- ofNullable: This method allows developers to create a stream from an optional value, without the need for null-checking. For example:
1String value = "Hello";
2Stream<String> stream = Stream.ofNullable(value);
3stream.forEach(System.out::println);
4// Output: Hello
5
- iterate: This method allows developers to create an infinite stream of elements, by applying a function to a seed element repeatedly. For example:
1Stream<Integer> stream = Stream.iterate(1, n -> n + 1);
2stream.limit(5).forEach(System.out::println);
3// Output: 1 2 3 4 5
4
- Improved parallel performance: Java 9 improved the performance of parallel streams by allowing them to be split more efficiently. This can be especially beneficial for large data sets and complex operations. For example:
1List<Integer> numbers = IntStream.range(1, 1000000).boxed().collect(Collectors.toList());
2long sum = numbers.parallelStream().mapToLong(Integer::longValue).sum();
3System.out.println("Sum: " + sum);
4
These are just a few examples of the new features and improvements in the Stream API in Java 9. For more information and more advanced usage, you can refer to the official Java documentation.
3. Reactive Streams: Java 9 introduced support for Reactive Streams, a specification for asynchronous stream processing with non-blocking back pressure. This allows developers to handle large amounts of data and complex operations in a more efficient and responsive way. Here are some examples of how to use the new features in Java 9:
- Publisher: The
Publisher
interface represents a source of stream data. It can be implemented by any class that can emit a stream of data, for example a database query or a web service call. Here's an example of a simple publisher that emits a stream of integers:
1class IntegerPublisher implements Publisher<Integer> {
2 private final List<Integer> numbers;
3 public IntegerPublisher(List<Integer> numbers) {
4 this.numbers = numbers;
5 }
6 @Override
7 public void subscribe(Subscriber<? super Integer> subscriber) {
8 for (Integer number : numbers) {
9 subscriber.onNext(number);
10 }
11 subscriber.onComplete();
12 }
13}
14
- Subscriber: The
Subscriber
interface represents a consumer of stream data. It can be implemented by any class that can receive and process a stream of data, for example a GUI component or a data storage class. Here's an example of a simple subscriber that prints the integers it receives:
1class IntegerPrinter implements Subscriber<Integer> {
2 @Override
3 public void onSubscribe(Subscription subscription) {
4 subscription.request(Long.MAX_VALUE);
5 }
6 @Override
7 public void onNext(Integer number) {
8 System.out.println(number);
9 }
10 @Override
11 public void onError(Throwable throwable) {
12 throwable.printStackTrace();
13 }
14 @Override
15 public void onComplete() {
16 System.out.println("Done");
17 }
18}
19
- Subscription: The
Subscription
interface represents a connection between a publisher and a subscriber. It allows the subscriber to control the flow of data, for example by requesting more data or cancelling the subscription. Here's an example of how to use a publisher and a subscriber together:
1List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
2Publisher<Integer> publisher = new IntegerPublisher(numbers);
3Subscriber<Integer> subscriber = new IntegerPrinter();
4publisher.subscribe(subscriber);
5
These are just basic examples of how to use the Reactive Streams features in Java 9. For more information and more advanced usage, you can refer to the official Reactive Streams specification, as well as the Java documentation for the Publisher
, Subscriber
, and Subscription
interfaces.
4. Improved Process API: Java 9 introduced an improved Process API, which provides a more powerful and flexible way to manage and control operating system processes. Here are some examples of how to use the new features in Java 9:
- Starting a process: The
ProcessBuilder
class has been enhanced in Java 9 to support more options when starting a new process. For example, you can now specify the working directory, environment variables, and redirect input and output streams. Here's an example of how to start a process that runs the "ls" command and redirects the output to a file:
1ProcessBuilder builder = new ProcessBuilder("ls", "-la");
2builder.directory(new File("/"));
3builder.redirectOutput(new File("output.txt"));
4Process process = builder.start();
5
- Managing a process: The
Process
class has been enhanced in Java 9 to provide more methods for managing and controlling a running process. For example, you can now check the process's exit value, destroy the process, and query its current state. Here's an example of how to wait for a process to complete and then check its exit value:
1int exitValue = process.waitFor();
2if (exitValue == 0) {
3 System.out.println("Process completed successfully");
4} else {
5 System.out.println("Process failed with exit code " + exitValue);
6}
7
- Monitoring a process: The
ProcessHandle
class has been introduced in Java 9 to provide more information about a running process, such as its process ID, parent process, and children processes. Here's an example of how to get the process ID of a running process:
1long pid = process.toHandle().getPid();
2System.out.println("Process ID: " + pid);
3
- Accessing the process tree: The
ProcessHandle
class also provides methods to access the process tree, such aschildren()
,descendants()
andisAlive()
. Here's an example of how to get the children process of a running process:
1ProcessHandle handle = process.toHandle();
2Stream<ProcessHandle> children = handle.children();
3children.forEach(child -> System.out.println("Child process: " + child.getPid()));
4
These are just a few examples of how to use the improved Process API in Java 9. For more information and more advanced usage, you can refer to the Java documentation for the ProcessBuilder
, Process
, and ProcessHandle
classes.
5. Private Interface Methods: Java 9 introduced the ability to include private and private static methods in interfaces. This allows for better code organization and encapsulation within interfaces, as well as the ability to share common code across multiple default methods. Here's an example of how to use private interface methods in Java 9:
1public interface MyInterface {
2 default void publicMethod() {
3 System.out.println("This is a public method");
4 privateMethod();
5 }
6
7 private void privateMethod() {
8 System.out.println("This is a private method");
9 }
10}
In this example, the interface MyInterface
has a public default method publicMethod()
and a private method privateMethod()
. The publicMethod()
is able to call the privateMethod()
as it is in the same interface.
You can also use a private static method in an interface in the same way:
1public interface MyInterface {
2 default void publicMethod() {
3 System.out.println("This is a public method");
4 privateStaticMethod();
5 }
6
7 private static void privateStaticMethod() {
8 System.out.println("This is a private static method");
9 }
10}
11
In this example, the interface MyInterface
has a public default method publicMethod()
and a private static method privateStaticMethod()
. The publicMethod()
is able to call the privateStaticMethod()
as it is in the same interface.
It should be noted that the private methods can't be accessed by the implementing classes. These methods are for internal usage within the interface.
This feature makes the code more readable and maintainable, as well as providing a way to share common code between multiple default methods in an interface. It also allows for better encapsulation of the implementation details within an interface.
These are just a few of the new features and improvements in Java 9. For a complete list and more detailed information, you can refer to the official Java 9 documentation.