DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Singleton: 6 Ways To Write and Use in Java Programming
  • The Long Road to Java Virtual Threads
  • Rust’s Ownership and Borrowing Enforce Memory Safety
  • Build a Java Microservice With AuraDB Free

Trending

  • Mastering Fluent Bit: Installing and Configuring Fluent Bit on Kubernetes (Part 3)
  • GDPR Compliance With .NET: Securing Data the Right Way
  • A Guide to Developing Large Language Models Part 1: Pretraining
  • Hybrid Cloud vs Multi-Cloud: Choosing the Right Strategy for AI Scalability and Security
  1. DZone
  2. Coding
  3. Java
  4. Exploring Exciting New Features in Java 17 With Examples

Exploring Exciting New Features in Java 17 With Examples

In this blog, we will learn about 5 new Java features: 1. Sealed Classes 2. Pattern Matching for Switch 3. Foreign Function Interface (FFI) 4. Memory API 5. Text Block

By 
Lav Kumar user avatar
Lav Kumar
·
Oct. 12, 23 · Analysis
Likes (7)
Comment
Save
Tweet
Share
25.3K Views

Join the DZone community and get the full member experience.

Join For Free

Java, one of the most popular programming languages, continues to evolve and improve with each new release. Java 17, the latest long-term support (LTS) version, brings several exciting features and enhancements to the language. In this article, we will explore some of the notable new features in Java 17 and provide practical examples to help you understand how to use them effectively.

Sealed Classes

Sealed classes allow you to restrict which classes or interfaces can extend or implement them. This feature enhances encapsulation and helps maintain code integrity by controlling who can inherit from a sealed class. Let's look at an example:

Java
 
public sealed class Shape permits Circle, Square, Triangle {
    // Common properties and methods for all shapes
}

final class Circle extends Shape {
    // Circle-specific properties and methods
}

final class Square extends Shape {
    // Square-specific properties and methods
}

final class Triangle extends Shape {
    // Triangle-specific properties and methods
}


Any other class that tries to extend the Shape class(apart from permit classes like Circle, Square, and Triangle)will result in a compilation error


The Ultimate Java Expert Certification Bundle.*

*Affiliate link. See Terms of Use.

Pattern Matching for Switch

 Java 17 introduces pattern matching for switch statements, which simplifies code by combining the declaration of a variable with its conditional check. Here's an example:

Java
 
public String getDayOfWeek(int day) {

            String dayOfWeek = switch (day) {

            case 1 -> "Monday";

            case 2 -> "Tuesday";

            case 3 -> "Wednesday";

            case 4 -> "Thursday";

            case 5 -> "Friday";

            default -> "Unknown";

        };

        return dayOfWeek;

    }


Foreign Function Interface (FFI)

An FFI allows a high-level programming language like Java to interact with functions or libraries written in lower-level languages like C or C++. Java has the Java Native Interface (JNI) for this purpose. JNI allows Java applications to call and be called by native applications and libraries. With JNI, you can load and invoke functions in dynamic link libraries (DLLs) or shared object files (SOs) written in languages like C or C++.

Here's a basic overview of using JNI in Java:

  • Write a Java class that contains native method declarations, specifying the native keyword.
  • Implement these native methods in C or C++ and compile them into a shared library.
  • Use the System.loadLibrary or System.load method in Java to load the shared library.
  • Call the native methods from your Java code.
  • Example:

Step 1: Write the Java Class

First, create a Java class that declares the native method. In this example, we'll call it NativeSum.java.

Java
 
public class NativeSum {
    // Load the shared library containing the native function
    static {
        System.loadLibrary("NativeSum");
    }

    // Declare the native method to add two integers
    public native int add(int a, int b);

    public static void main(String[] args) {
        NativeSum nativeSum = new NativeSum();
        int result = nativeSum.add(5, 7);
        System.out.println("Sum: " + result);
    }
}


Step 2: Write the Native C Code

Next, create a C file that implements the native method. In this example, we'll call it NativeSum.c.

C
 
#include <jni.h>

JNIEXPORT jint JNICALL Java_NativeSum_add(JNIEnv *env, jobject obj, jint a, jint b) {
    return a + b;
}


Step 3: Compile the Native Code

Compile the native C code into a shared library. The exact steps to do this depend on your development environment and platform. Here's a simple example of using GCC on a Unix-like system:

gcc -shared -o libNativeSum.so -I$JAVA_HOME/include -I$JAVA_HOME/include/linux NativeSum.c

Replace $JAVA_HOME with the path to your Java installation.

Step 4: Run the Java Program

Now, you can run the Java program

Java
 
java NativeSum


This program will load the libNativeSum.so shared library and call the add method, which adds two integers and returns the result. In this case, it adds 5 and 7 and prints "Sum: 12."

Memory API

Java provides memory management through its own mechanisms, and Java developers typically do not need to deal directly with memory allocation or deallocation. Java's memory management includes automatic garbage collection, which cleans up memory that is no longer in use. The Java Virtual Machine (JVM) takes care of memory management for you.

However, if you have specific memory-related requirements or need to work with off-heap memory, you might use third-party libraries or features such as Java's NIO (New I/O) package. NIO allows for more direct and efficient memory manipulation, including memory-mapped files, buffers, and channels. It can be useful for certain low-level operations and high-performance I/O.

Here's an example of using Java's New I/O (NIO) package to work with memory-mapped files and memory buffers.

Step 1

In this example, we'll create a simple program that reads and writes data to a memory-mapped file using memory buffers.

Java
 
import java.io.RandomAccessFile;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;

public class MemoryMappedFileExample {
    public static void main(String[] args) throws Exception {
        // Create a random access file for read and write operations
        RandomAccessFile file = new RandomAccessFile("example.txt", "rw");

        // Get the file channel
        FileChannel channel = file.getChannel();

        // Map the file into memory
        MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);

        // Write data to the memory-mapped file
        String data = "Hello, Memory-Mapped File!";
        buffer.put(data.getBytes());

        // Read data from the memory-mapped file
        buffer.flip();
        byte[] readData = new byte[data.length()];
        buffer.get(readData);

        System.out.println(new String(readData));

        // Close the file and channel
        channel.close();
        file.close();
    }
}


In this example, we create a memory-mapped file called "example.txt," write some data to it, read it back, and print it.

Step 2: Compile and Run

Compile and run the Java program. It will create a file named "example.txt" in the current directory and write "Hello, Memory-Mapped File!" to it. It then reads the data from the memory-mapped file and prints it.

Please note that the memory-mapped file can be larger than the physical memory because it uses the virtual memory system of the operating system. The mapped data is directly read from and written to the file without explicitly loading the entire file into memory.

Text Block

In Java 17, a new feature known as "Text Blocks" was introduced to simplify the writing of multiline strings and make the code more readable when working with long text content. Text Blocks allow you to write multi-line strings in a more natural and concise way. They are enclosed within triple double quotes, and indentation is preserved. Here's an example of how to use Text Blocks:

Java
 
public class TextBlocksExample {
    public static void main(String[] args) {
        String longText = """
            This is a text block in Java 17.
            It allows you to write multi-line strings
            without needing to escape newline characters.
            
            You can also preserve leading whitespace for formatting.
            \tIndented text is also preserved.
            """;

        System.out.println(longText);
    }
}


In this example, we use Text Blocks to create a multi-line string. You can see that the indentation is preserved, and you don't need to manually escape newline characters with \n. This makes it much easier to write and maintain large blocks of text within your code.

Text Blocks are particularly useful when working with SQL queries, JSON, HTML, XML, or any other text-based content that spans multiple lines. They help improve code readability and maintainability.

Text Blocks were introduced as a preview feature in Java 13 and further enhanced in Java 14, 15, and 16 before becoming a standard feature in Java 17.

Java virtual machine Data (computing) Java (programming language) Memory (storage engine) Strings Data Types Feature selection Function type Java EE User-defined function

Opinions expressed by DZone contributors are their own.

Related

  • Singleton: 6 Ways To Write and Use in Java Programming
  • The Long Road to Java Virtual Threads
  • Rust’s Ownership and Borrowing Enforce Memory Safety
  • Build a Java Microservice With AuraDB Free

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service