top of page

Exploring the Depths of Java 9 Features with Comprehensive Examples

Updated: Aug 18

Java 9 has revolutionized the programming landscape with its array of powerful features. These enhancements improve how developers build applications, making the coding experience smoother and more efficient. This post highlights the most impactful features of Java 9, using clear examples to illustrate their practical applications.

ree

Understanding the Update in Java 9


Released in September 2017, Java 9 marked a transformative moment for the Java programming language. The standout introduction was the Java Platform Module System (JPMS), which enables developers to modularize their applications. This modularity not only organizes code better but also significantly boosts performance and security.


Beyond modularity, Java 9 brought in valuable tools like the JShell for hands-on programming, enhancements to the Stream API, and improvements in the Java Collections Framework. This post delves into these features with detailed explanations and examples.


The Java Platform Module System (JPMS)


A Closer Look at JPMS


The Java Platform Module System (JPMS) represents a revolutionary step in Java’s evolution. It allows developers to modularize their applications, which leads to better organization and increases performance and security. Modularization enables developers to manage dependencies effectively, ensuring that code remains clean and maintainable.


JPMS Example


To demonstrate JPMS, let's create a basic modular application.


  1. Setting Up a Module: Start by establishing a module structure named `com.example.helloworld`.


com.example.helloworld/

├── src/

│   └── com.example.helloworld/

│       ├── HelloWorld.java

│       └── module-info.java

  1. Module Definition: In the `module-info.java`, define the module and set its exports like this:


module com.example.helloworld {

    exports com.example.helloworld;

}

  1. Class Implementation: Next, implement a simple class in `HelloWorld.java`.


package com.example.helloworld;



public class HelloWorld {

    public static void main(String[] args) {

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

    }

}

  1. Run the Application: Compile and run the application with these commands:


javac -d out --module-source-path src $(find src -name "*.java")

java --module-path out -m com.example.helloworld/com.example.helloworld.HelloWorld

This example showcases how JPMS allows effective dependency management through simple modularization of components.


Exploring JShell: The Java Shell Tool


Overview of JShell


JShell is an interactive command-line tool introduced in Java 9. It enables developers to run Java code snippets directly, making it especially useful for testing and learning. Instead of needing a full development setup, developers can experiment with Java code quickly and efficiently.


Example Usage of JShell


To start using JShell, simply enter `jshell` in your terminal. Here’s a straightforward illustration:


$ jshell

|  Welcome to JShell -- Version 9

|  For an introduction type: /help intro



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

   ...>     return a + b;

   ...> }

|  created method sum(int,int)



jshell> sum(5, 10)

$1 ==> 15

In this interaction, we created a method `sum` that adds two numbers. When called with `5` and `10`, JShell provides an immediate response of `15`. This feature encourages rapid experimentation, helping developers refine their skills and concepts.


Enhancements to the Stream API


Stream API Advancements


Java 9 introduced vital enhancements to the Stream API, aimed at making it more user-friendly and efficient. Two significant new methods are `takeWhile` and `dropWhile`, offering more flexibility when processing collections.


Examples of New Stream Methods


  1. Using `takeWhile`: This method yields a stream containing the longest prefix of elements that meet a specified condition.


import java.util.List;

import java.util.stream.Collectors;



public class StreamEnhancements {

    public static void main(String[] args) {

        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        

        List<Integer> result = numbers.stream()

            .takeWhile(n -> n < 5)

            .collect(Collectors.toList());

        

        System.out.println(result); // Output: [1, 2, 3, 4]

    }

}

In this instance, `takeWhile` captures numbers from the list until we reach a number that does not fulfill the condition (less than 5).


  1. Using `dropWhile`: Conversely, this method returns a stream of remaining elements after skipping the longest prefix that meets the condition.


import java.util.List;

import java.util.stream.Collectors;



public class StreamEnhancements {

    public static void main(String[] args) {

        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        

        List<Integer> result = numbers.stream()

            .dropWhile(n -> n < 5)

            .collect(Collectors.toList());

        

        System.out.println(result); // Output: [5, 6, 7, 8, 9, 10]

    }

}

Here, `dropWhile` allows us to bypass numbers less than 5, displaying what remains.


  1. Using `ofNullable`: This method creates a stream from a single value, returning an empty stream if the value is null.


import java.util.stream.Stream;



public class StreamEnhancements {

    public static void main(String[] args) {

        String value = null;

        

        Stream<String> stream = Stream.ofNullable(value);

        

        System.out.println(stream.count()); // Output: 0

    }

}

In this example, because the value is null, `ofNullable` results in an empty stream.


Advancements in the Java Collections Framework


Overview of Collections Framework Enhancements


Java 9 delivered improvements to the Collections Framework, including new factory methods for creating immutable collections. This innovation simplifies collection creation while enhancing the overall readability of the code.


Example of Creating Immutable Collections


Let’s see how to create immutable lists, sets, and maps using the new factory methods.


  1. Creating an Immutable List:


import java.util.List;



public class CollectionsImprovements {

    public static void main(String[] args) {

        List<String> fruits = List.of("Apple", "Banana", "Cherry");

        

        System.out.println(fruits); // Output: [Apple, Banana, Cherry]

    }

}

With just a single line, we created an immutable list of fruits.


  1. Creating an Immutable Set:


import java.util.Set;



public class CollectionsImprovements {

    public static void main(String[] args) {

        Set<String> colors = Set.of("Red", "Green", "Blue");

        

        System.out.println(colors); // Output: [Red, Green, Blue]

    }

}

Here, we managed to create a set that cannot be modified.


  1. Creating an Immutable Map:


import java.util.Map;



public class CollectionsImprovements {

    public static void main(String[] args) {

        Map<String, Integer> scores = Map.of("Alice", 90, "Bob", 85);

        

        System.out.println(scores); // Output: {Alice=90, Bob=85}

    }

}

This example illustrates how straightforward it is to create immutable maps with the `Map.of` method.


Wrapping Up


Java 9 introduced powerful features that profoundly enhance the Java programming experience. With JPMS enabling modular applications, JShell for interactive coding, and improvements to the Stream API and Collections Framework, developers can write cleaner and more efficient code.


By leveraging these features, you can create applications that are not only well-organized but also easier to maintain. As Java continues to evolve, embracing these advancements will keep your projects aligned with industry standards and best practices. Enjoy coding!


Perfect 👍 Let’s build you a comprehensive list of Java 9 interview questions just like I did for Java 8. These will cover new features, coding tasks, comparisons with earlier versions, and real-world use cases.


Java 9 Interview Questions

1. Overview

  • What are the major new features in Java 9?

  • Why was Java 9 considered an important release?

  • Compare Java 8 vs Java 9.

2. Java Platform Module System (JPMS / Project Jigsaw)

  • What is the Java Platform Module System?

  • Why was JPMS introduced in Java 9?

  • How do you create a module in Java 9?

  • What is module-info.java?

  • What are requires, exports, and opens in module descriptors?

  • Difference between exports and opens.

  • How do you handle reflection in modular Java applications?

  • What are automatic modules?

  • What is the difference between unnamed modules and named modules?

  • How does JPMS improve encapsulation and security?

  • Challenges in migrating legacy applications to Java 9 modules.

3. JShell (REPL)

  • What is JShell in Java 9?

  • How do you start JShell?

  • What problem does JShell solve for developers?

  • Can you run scripts in JShell?

  • Example: Show how to test a lambda in JShell.

  • Difference between JShell and a normal Java compiler.

4. Streams API Enhancements

  • What new methods were added to Streams in Java 9?

  • Explain takeWhile() and dropWhile() with examples.

  • What is the difference between limit() (Java 8) and takeWhile() (Java 9)?

  • What does Stream.iterate() do in Java 9?

  • Example: Generate a stream of even numbers up to 20 using iterate().

5. Optional Enhancements

  • What new methods were added to Optional in Java 9?

  • Difference between ifPresent() (Java 8) and ifPresentOrElse() (Java 9).

  • How does Optional.stream() simplify code?

  • Example: Use Optional.or() in practice.

6. Process API Updates

  • What improvements were made in Process API in Java 9?

  • How do you get process information (PID, CPU time, user) in Java 9?

  • What is ProcessHandle?

  • Can you kill a process in Java 9 using API?

7. Interface Private Methods

  • Why were private methods in interfaces introduced in Java 9?

  • Difference between default, static, and private methods in an interface.

  • Example of a private helper method in an interface.

8. New HTTP/2 Client (Incubator)

  • What is the new HTTP/2 client introduced in Java 9?

  • Why was it needed when HttpURLConnection already existed?

  • Difference between old HttpURLConnection and the new HttpClient.

  • Example: Write code to send a GET request using Java 9 HTTP client.

  • What is asynchronous HTTP communication in Java 9?

9. Other Enhancements

  • What are factory methods for collections in Java 9? Give examples.

  • Difference between List.of(), Set.of(), and Map.of().

  • Can collections created with List.of() be modified?

  • What is the Stack-Walking API in Java 9?

  • What are multi-release JAR files (MRJARs)?

  • What are compact strings in Java 9? How do they optimize memory?

  • What is the difference between String in Java 8 and Java 9?

  • What is the difference between G1 Garbage Collector in Java 8 and Java 9?

  • What is the role of @SafeVarargs changes in Java 9?

  • Explain enhancements in deprecation handling (@Deprecated with attributes since and forRemoval).

  • What is the new ProcessHandle.onExit() method?

10. Removed / Deprecated Features

  • Which features/APIs were removed in Java 9?

  • Why was Java EE and CORBA modules removed from JDK 9?

  • What is the difference between “deprecated” in Java 8 vs Java 9?

  • Why was Applet API deprecated?

11. Real-World & Scenario-Based

  • How would you migrate a Java 8 application to Java 9 with modules?

  • How do you split a large monolithic application into modules?

  • What are the challenges in using JPMS with frameworks like Spring or Hibernate?

  • How do you use ProcessHandle to monitor child processes in real-time?

  • Example: Use Stream.takeWhile() to read lines from a file until a blank line appears.

  • Example: Create an immutable map of countries and capitals using Java 9 factory methods.

  • Write code to send asynchronous requests with Java 9 HttpClient.


Related Posts

See All

Comments


bottom of page