Deprecated Features in Java 18 thru 21 - Sip of Java

Many new features have been added to Java between 18 and 21, but some features are also on the way out. Let’s review a few key features that have been deprecated or removed and alternatives for them!


The biggest feature to be deprecated between Java 18 and 21 period was the deprecation for removal of finalization. This change was part of Java 18 and covered in JEP 421.

Finalization has been part of Java since 1.0 but never worked as intended. The reasons for this are many, and if you are interested, be sure to read the JEP, which also includes some real-world consequences of finalization not working correctly.

There are several options for preparing your applications for the removal of finalization.

The first and most direct would be simply turning off finalization with the command-line option: --finalization=disabled. This turns off all finalizers, even those within the JDK itself. If your application experiences no issues, then your work might be done.

If you experience some issues, JDK Flight Recorder (JFR) has been updated with the new jdk.FinalizerStatistics event for tracking calls to finalize(). Enable JFR like here:

$ java -XX:StartFlightRecording:filename=recording.jfr ... 

And print out instances of jdk.FinalizerStatistics with:

jfr print --events FinalizerStatistics recording.jfr

This can provide a starting point for where changes might be needed. If the changes to remove finalize() are in your code, there are a couple of options to consider.

Consider updating the classes using finalize() to implement Closeable or AutoCloseable and moving the behavior of releasing resources to close(). This would ensure the prompt release of resources on leaving a try-with-resources block:

try(MyCloseableResource res = new MyCloseableResource(){

If this does not work, consider using the Cleaner API added in JDK 9. Rodger Riggs wrote a great article on how to use the Cleaner API.


The constructors for java.util.Locale were deprecated in JDK 19 as covered in JBS issue JDK-8282819. The static factory method options should be used instead.

The most direct replacement would be the .of methods:

  • Locale Locale.of(String)
  • Locale Locale.of(String, String)
  • Locale Locale.of(String, String, String)

There is also:

  • Locale Locale.forLanguageTag(String)

And the Locale.Builder as well.

Emit Warning for Removal of COMPAT Provider (JDK-8304982)

In JDK 9, Java moved from using COMPAT to CLDR for Locale data as default; this change was covered in JEP 252. JBS issue JDK-8304982 specifies that a warning will be emitted when COMPAT is used. The removal of COMPAT could come as soon as JDK 22.

Remove the JAR Index Feature (JDK-8302819)

The JAR Index feature was removed in JDK 21. The JAR Index feature is an old optimization primarily meant to benefit applets, which are similarly on their way out. There isn’t a replacement for the JAR index feature, and a warning will be emitted when -i or --generate-index are used.

See: JDK-8302819

Happy coding!