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
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
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

Migrate, Modernize and Build Java Web Apps on Azure: This live workshop will cover methods to enhance Java application development workflow.

Modern Digital Website Security: Prepare to face any form of malicious web activity and enable your sites to optimally serve your customers.

Kubernetes in the Enterprise: The latest expert insights on scaling, serverless, Kubernetes-powered AI, cluster security, FinOps, and more.

A Guide to Continuous Integration and Deployment: Learn the fundamentals and understand the use of CI/CD in your apps.

Related

  • Rust’s Ownership and Borrowing Enforce Memory Safety
  • Build a Java Microservice With AuraDB Free
  • Mule 3 DataWeave(1.x) Script To Resolve Wildcard Dynamically
  • High-Performance Java Serialization to Different Formats

Trending

  • Micro Frontends Architecture
  • Scaling SRE Teams
  • Ways To Reduce JVM Docker Image Size
  • CI/CD Metrics You Should Be Monitoring
  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

Lav Kumar user avatar by
Lav Kumar
·
Oct. 12, 23 · Analysis
Like (6)
Save
Tweet
Share
7.0K 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

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

  • Rust’s Ownership and Borrowing Enforce Memory Safety
  • Build a Java Microservice With AuraDB Free
  • Mule 3 DataWeave(1.x) Script To Resolve Wildcard Dynamically
  • High-Performance Java Serialization to Different Formats

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

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

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: