Java JDK: Overview of versions, differences between LTS, SE, JRE and Java 24
We bring you an overview of Java versions, a comparison of the Java JDK, SE and LTS releases, and a summary of the most important changes in the latest versions – including Java 24, which once again pushes the boundaries of the language one step further. You’ll get a clear picture of what the main differences between the versions are, what the new features bring, and what to look out for when migrating.

V článku sa dozvieš:
Java versions of JDK, SE, LTS and frequency of releases
Java has been in continuous development for more than two decades, and to keep up with modern development requirements, it has switched to a semi-annual release model. The first agile version was Java SE 9, which was released in September 2017. The Java 10 version subsequently appeared six months later. Every six months, a new version of the Java JDK is released, bringing improvements, fixes and experimental features.
It is crucial for companies and developers to understand the difference between LTS (Long-Term Support) releases, which provide stability and long-term support, and non-LTS releases, which are more for testing new features and preparing for future LTS releases.


Java JDK (Java Development Kit)
Java JDK (Java Development Kit) is the official toolkit for developing applications in Java. It includes a compiler javac
, which translates source code into bytecode executable on the Java Virtual Machine (JVM), a debugger, standard API libraries, documentation, and various tools for managing and testing applications. Thus, the JDK is essential for any developer because it provides a complete environment for writing, compiling, running, and debugging code.
In addition to the basic tools, the JDK offers various helper utilities, such as javadoc
for generating documentation directly from source code or jlink
for creating custom Java runtime images. It is important to distinguish it from the Java Runtime Environment (JRE), which is only used to run ready-made applications. While the JRE is used by end users, the JDK is intended primarily for developers – without it, Java applications could not be created or tested.
Java SE(Java Platform, Standard Edition)
Java SE (Java Platform, Standard Edition) is the base edition of the Java platform that defines the standardized APIs, syntax, and behavior of the language. It contains key libraries and packages such as Collections, Concurrency, I/O, Networking, Security, and XML processing. With Java SE, there is a common foundation on which all Java applications and frameworks – from simple desktop programs to large-scale enterprise solutions – are built.
Java SE is not a development tool like the JDK, but rather a “standard” and a specification of what each version of Java should contain. It is the official language definition that all Java implementations (e.g. OpenJDK) must follow. For developers, it provides assurance that code written according to Java SE will work in any environment compatible with this standard.
JRE (Java Runtime Environment)
The Java Runtime Environment (JRE) is an environment designed to run applications written in Java. It contains the Java Virtual Machine (JVM), which handles the translation and execution of the bytecode, as well as the core libraries needed to run the programs. Unlike the JDK, it does not provide development tools – its role is only to ensure that the finished application can run on a computer or server.
Thus, JRE is suitable for end users or production environments where applications are only run but not further developed. A developer can usually get by with a JDK (which the JRE automatically includes), while a standalone JRE will be used by those who only run the applications.
Java LTS (Long-Term Support)
Java LTS (Long-Term Support) represents versions of Java that have guaranteed long-term support from Oracle or other vendors (Adoptium, Red Hat, etc.). Each LTS release comes out approximately every three years and provides companies with stability, security patches and bug fixes for 8 years or more. This is why LTS releases are the most common choice for enterprise projects where reliability and minimal operational risk are key.
Unlike non-LTS versions, which are supported for only 6 months and are mainly for testing new features, LTS versions act as stable milestones in Java’s history. Developers and companies typically migrate directly from one LTS to the next (e.g., from Java 11 to 17 or 21), thus avoiding the problems associated with short-term releases. LTS thus provides a secure foundation for long-term projects and production environments.
Differences between Java JDK, SE, LTS, JRE
Criterion | LTS (Long-Term Support) | non-LTS | JDK (Java Development Kit) | Java SE (Standard Edition) | JRE (Java Runtime Environment) |
---|---|---|---|---|---|
Length of support | 8+ years (Oracle, vendor support) | 6 months | Includes compiler javac , tools, debugger, documentation, libraries |
Platform and API defined by standard (JLS, JVM, libraries) | Includes JVM + core libraries, no development tools |
Issue | Every 3 years (e.g. Java 11, 17, 21) | Semiannually (e.g. Java 12, 13, 14…) | Distributed with every version of Java (LTS and non-LTS) | Defines what each version of Java “must have” | Bound to a specific version of Java, released with the JDK |
Stability | Very stable, recommended for business and production | More experimental, bring new features faster | Provides all the development tools to work with Java | Includes basic APIs (Collections, Streams, IO, Concurrency, etc.) | Stable environment to run applications |
Target group | Corporations, enterprise solutions, long-term projects | Developers, testing new features | Programmers and development teams | The entire Java community (standardization) | End users and environments where applications are only run |
Risk | Minimal, long-term fixes and security patches | Higher – possible feature removal in next release | No extra risk – tied to a specific version | Stability – defines the official foundation of Java | No risk – does not include development tools, only runtime |
Examples | Java 8, Java 11, Java 17, Java 21 | Java 9, 10, 12, 13, 14, 15, 16, 18… | JDK 11, JDK 16, JDK 24… | Java SE 9, SE 18, SE 25… | JRE 8, JRE 11, JRE 17… |
LTS versions are the choice for stability and long-term support. Companies deploy them in production because they receive security patches and fixes for several years.
On the contrary, non-LTS versions are short-lived – they come out every six months and bring faster innovations. Developers use them to test new features, but in production they are usually moved to the next LTS.
The Java Development Kit (JDK) is a package of tools that you get with every version of Java and is used directly by developers.
Java SE (Standard Edition) defines the core language standard and API on which the entire ecosystem is built.
- LTS versions → stability, long-term support, suitable for production
- non-LTS versions → short-term, introducing new features, suitable for testing
- JDK (Java Development Kit) → developer tools (compiler, debugger, libraries)
- Java SE (Standard Edition) → the core standard and API on which all of Java is based
So if you’re deciding which version to choose:
- For a long-term project, reach for LTS.
- For experiments and rapid adoption of new features, non-LTS is suitable.
Migration between Java JDK versions
Migrating to a new version of Java is not just about downloading the latest JDK. It’s a process that requires planning, testing, and customization of existing code.
The main steps of migration:
- Project analysis
- Check what libraries and frameworks you use.
- Check if they are compatible with the target version of Java.
- Check for removed and deprecated APIs
- For new releases, some features are marked as deprecated and later removed completely.
- Typical examples: old security algorithms, internal sun.* APIs.
- Compatibility testing
- Run existing tests on the new JDK version.
- Watch for warnings and compilation errors.
- Modification of build and CI/CD pipeline
- Update build tools (Maven, Gradle).
- Make sure the CI/CD pipeline is running on the correct JDK version.
- Gradual transition
- For large projects it is advisable to switch from LTS to LTS (e.g. from 11 → 17 → 21).
- This avoids inter-version problems and keeps you stable.
- Power and regression testing
- Test your application under load to detect any slowdowns or memory leaks.
The most common problems in migration:
- Unsupported libraries – older dependencies may not work on the new JDK.
- Removed APIs – if the project uses an internal JDK API, this may cause errors.
- Security changes – stricter TLS/SSL settings may block legacy connections.
It is always safest to migrate to the latest LTS version, test the application, and then deploy it to production. Non-LTS versions are good for experimentation, but not for long term running applications.ň
Next, we will discuss the changes and improvements in each Java version in detail.
Java SE 24
Java 24 brought a new version of the JDK 24 with a symbolic 24 enhancements to the language, API, platform performance, stability and security. We haven’t had a release this bursting with new features in a long time. So let’s not waste time and let’s introduce them one by one.
Java JDK 24 brings several changes and improvements
The new version of Java 24 was brought out by Oracle on March 18, 2025. The complete Java Development Kit 24 (JDK 24) for this version of Java brings a number of enhancements for programmers.
Java 24, including the release notes, is available for download at this link
Like previous versions of Java, Java 24 is a collective effort of many contributors, both individuals and organizations in the OpenJDK community. While the number of changes in JDK releases has remained roughly the same for several years, the pace at which new features and enhancements are released into production has accelerated significantly over the last six-month cycle.

Changes in JDK 24 range from major new features to minor enhancements to routine maintenance, bug fixes and documentation improvements. Each change for a given ticket is represented by a separate commit to the JDK Bug System repository.
You know… …between Java 11 and Java 24, 31,187 problems have been solved? 22,107 (approx. 70%) were completed by people working for Oracle, while 9,080 (approx. 30%) were contributed by individual developers working either independently or for other organizations. In Java 24 of the 2,463 JIRA issues marked as fixed, 1,657 were completed by Oracle (approx. 67%), while 806 (approx. 33%) were contributed by other members of the Java community.
JDK 24 introduces 24 enhancements , which are significant enough to receive their own JDK – JEP enhancement suggestions , including 8 feature demos and 1 incubator feature.
Oracle JDK 24 Language Features
Primitive Types in Patterns, instanceof, and switch (sample 2)
JEP 488: Extends pattern matching to allow type patterns with primitive types in all contexts, while adding instanceof and switch operators to support all primitive types, including safe testing and conversions. This achieves a unified, more expressive language for processing values and types without manual retyping or range checks.
Flexible Constructor Bodies (sample 3)
JEP 492: Allows the insertion of common commands before explicit calls to super(…) or this(…) in the body of the constructor; these commands may initialize fields and validate arguments, but may not use an as-yet-unfinished object. This provides a more natural model for validating and preparing data before creating a superclass, simplifying and clarifying the code of constructors.
Module Import Declarations (sample 2)
JEP 494: Introduces a new syntax construct, import module M;, which imports all public top-level classes and interfaces exported by module M (including transitive dependencies) via a single command. This eliminates the need for many import … .* commands and greatly simplifies the reuse of module libraries in all types of projects.
Simple Source Files and Instance Main Methods (sample 4)
JEP 495: Brings a simpler way to create small Java programs: allows to write executable programs without custom classes and without boilerplate public static void main(String[] args), supports instance main methods (without parameter and modifiers) and simple source files with automatic imports of basic console I/O methods and the whole java.base module. This reduces the learning curve while maintaining the ability to smoothly transition to full programs.
Oracle JDK 24 libraries
Class-File API
JEP 484: Introduces a standardized API(java.lang.classfile) for parsing, generating and transforming .class files according to the format defined by the JVM specification. The goal is to replace the internal ASM libraries with a unified, maintainable and fully specified interface.
Stream Gatherers
JEP 485: Extends the Stream API with the ability to define custom intermediate operations (Stream::gather) that allow customized transformations of stream elements (one-to-one, one-to-many, many-to-many) with full parallelization support and without the need for external data collectors. This simplifies the expressive and efficient processing of data pipelines.
Scoped Values (sample 4)
JEP 487: Introduces a new ScopedValue type for sharing immutable data within a method, its calls, and newly created threads as a simpler and more powerful alternative to ThreadLocal. It has lower space and time requirements and is particularly useful when using virtual threads.
Vector API (9th incubator)
JEP 489: Introduces a platform-neutral, high-performance interface for expressing vector computations that maps at runtime to native SIMD instructions on supported CPUs. As a result, developers can achieve better performance than through equivalent scalar computations, which are increasingly used in AI computing.
Structured Concurrency (sample 4)
JEP 499: Allows groups of related tasks to be managed as a single unit of work via a new API, simplifying error management, cancellation and observability in competing applications. This concept helps prevent “thread leaks” and improves code reliability and readability.
Oracle JDK 24 security libraries
Key Derivation Function API (sample)
JEP 478: Introduces the new javax.crypto.KDF API for generating and distributing cryptographic keys using standard KDF algorithms such as HKDF (RFC 5869) and Argon2 (RFC 9106). It allows applications to easily derive multiple keys from a single input secret key (e.g., in Hybrid Public Key Encryption or TLS 1.3) and provides an interface for extensibility to other KDF implementations.
Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
JEP 496: Delivers an implementation of ML-KEM, a quantum-resilient KEM scheme standardized in NIST FIPS 203. Extends KeyPairGenerator, KEM, and KeyFactory with the ML-KEM-512, ML-KEM-768, and ML-KEM-1024 parameter sets, enabling applications to securely exchange symmetric keys resistant to attacks by future quantum computers.
Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
JEP 497: Adds support for ML-DSA, a quantum-resistant algorithm for digital signatures (FIPS 204). Implements KeyPairGenerator, Signature, and KeyFactory for the three parameter sets ML-DSA-44, ML-DSA-65, and ML-DSA-87, enabling authentication and data integrity verification with resistance to quantum attacks.
Oracle JDK 24 Tools
Linking Run-Time Images without JMODs
JEP 493: Allows you to create runtime images without JMOD files via jlink, reduces JDK installation size by up to 25%, and facilitates module management in cloud and container environments.
Improving Oracle JDK 24 runtime performance
Compact Object Headers (experimental)
JEP 450: Reduces the size of Java object headers from 96-128 bits to 64 bits on 64-bit platforms, which saves memory and improves data locality in the cache. Activated by VM options:
-XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders.
Late Barrier Expansion for G1
JEP 475: Moves memory barrier expansion in G1 GC from the early stages of C2 compilation to later stages, reducing compilation time and simplifying implementation while preserving the performance of the generated code.
Ahead-of-Time Class Loading & Linking
JEP 483: Improves JVM startup by caching loaded and pre-linked classes during a single startup, which HotSpot will use on the next startup, thus reducing initial startup time.
ZGC: Remove the Non-Generational Mode
JEP 490: Removes Non-Generational mode for Z Garbage Collector (-XX:+ZGenerational), reducing code complexity and making generational ZGC primary, more suitable for most deployments.
Synchronize Virtual Threads without Pinning
JEP 491: Improves the scalability of synchronized blocks when using virtual threads by not holding the platform thread when blocking, but releasing it for other threads, increasing the number of virtual threads served.
Source code Oracle JDK 24
Generational Shenandoah (experimental)
JEP 404: Introduces an experimental generational mode to Shenandoah GC that improves sustained throughput, resilience under sudden loads, and memory utilization by partitioning the heap into generational regions, without disrupting the existing non-generational mode. The goal is to prepare generational Shenandoah as the default mode in future releases.
Prepare to Restrict the Use of JNI
JEP 472: Started issuing runtime warnings on JNI and Foreign Function & Memory API calls to prepare developers for an upcoming release that will reduce or disable implicit support for native interaction. The JNI option is retained, but with clear warnings and consistent behavior before moving to tighter restrictions.
Remove the Windows 32-bit x86 Port
JEP 479: Removes the source code and build-script for the Windows 32-bit x86 port (deprecated in JDK 21), removing all specific paths and tests for this port. When Windows 10 support for 32-bit is discontinued (EOL October 2025), the JDK build and test infrastructure will be simplified.
Permanently Disable the Security Manager
JEP 486: The platform specification is modified so that the Security Manager can no longer be enabled in any way and its API will not be referenced in any way in the code, thus removing an obsolete and expensive security mechanism that was deprecated back in Java 17.
Warn upon Use of Memory-Access Methods in sun.misc.Unsafe
JEP 498: The first time any of the memory-access APIs are called in sun.misc.Unsafe, the JVM prints a runtime warning. These methods have been deprecated in JDK 23 and are to be replaced by standard encryption and memory interfaces.
Deprecate the 32-bit x86 Port for Removal
JEP 501: Announces the deprecation of the last 32-bit x86 port (Linux), preparing for its complete removal in JDK 25. After the removal, only the agnostic Zero port will remain for platforms with 32-bit architecture.
Sources:
- https://blogs.oracle.com/java/post/the-arrival-of-java-24
- https://openjdk.org/projects/jdk/24/
Java SE 23
Java as a programming language continues to dominate for today’s technology trends. Even the release of Java 23, with its many enhancements, shows that thoughtful planning and deadlines set and met in advance have contributed to making Java and its ecosystem the platform of choice for many developers worldwide for modern software development.
Overview of Java enhancements (JEPs) over the last 10 years

Java 23 SE
Java 23 was released on 17 September 2024. As with previous Java releases, Java 23 is the collective result of contributors, both individuals and organizations in the OpenJDK community.
The number of changes in JDK updates has remained largely constant over the past few years (averaging around 10), but this is due to the regular six-monthly releases, which, despite the relatively short lead time, range from new language features to small enhancements to existing functionality, to bug fixes and documentation updates.
Each change for a given ticket is represented by a separate commit to the JDK Bug System repository. Interestingly, there were 28,724 issues resolved between Java 11 and Java 23, with 20,450 (approx. 71%) completed by people working for Oracle, while 8,274 (approx. 29%) were contributed by individual Java developers working either independently or for other organizations.
Primitive types in patterns, instaceof and switch (example)
This change (JEP 455) will remove several limitations that exist when using primitive types in pattern matching. Code that handles primitive types and object types can be simplified when no special modifications are needed and both types can be handled in the same way. Allowing an instanceof to accept primitives further reduces the code for common instances because it can now automatically handle conditional overrides – where a value needs to be checked to ensure that it is valid for the target type.
Declarations for importing modules (example)
JEP 476 allows developers to import all packages exported by the module using a single command. This simplifies the reuse of modular libraries without requiring the code in the module itself to be imported. With this feature, beginners can use third-party libraries and basic Java classes without having to learn where they are located in the package hierarchy.
Implicitly declared classes and instance main methods (3rd example)
JEP 477 allows beginners to write their first Java programs without first having to understand features designed for larger and more complex programs. Simple programs can use simplified declarations and, if necessary, be easily extended with more advanced features as needed. Experienced developers can also enjoy the brevity of writing small programs.
Flexible constructor bodies (2nd example)
JEP 482 – By allowing some statements in constructors to appear before the explicit invocation of the constructor, i.e. super(…) or this(…), developers gain the freedom to better express the behaviour of constructors. The more natural placement of logic that this feature provides removes the need to incorporate some of the control and initialization logic into auxiliary static methods and auxiliary intermediate constructors. For example, if the constructor can check the arguments it receives before invoking the superclass constructor, it will fail quickly, avoiding an unnecessary superclass instance when the arguments are invalid.
Class-File API (2nd preview)
JEP 466 – This JEP proposes an API for parsing, generating and transforming Java class files that follows the format defined by the Java Virtual Machine specification. If this API is delivered as part of each release, it will alleviate the tension caused by Java adopting a six-month cycle between releases and frameworks that handle class files that are updated at each release in order to quickly adopt new versions. When completed, this functionality should free the JDK itself from its dependency on the third-party ASM library.
Vector API (8th incubator)
JEP 469 enables Java developers to express vector computations that compile reliably at runtime into optimal vector instructions on supported CPU architectures, achieving performance better than equivalent scalar computations. There are no differences from the 7th incubation of this feature in JDK 22. It is expected that this API will continue to return as an incubation API, at best with only minor changes, until the necessary features from the Valhalla project are available.
Stream gatherers (2nd preview)
JEP 473 enhances the Stream API to support custom intermediate operations. This will allow stream pipelines to transform data in ways that are not readily achievable with existing built-in intermediate operations. Stream gatherers provide the flexibility for intermediate operations that gatherers for terminal operations allow. This enhancement introduces five built-in gatherers.
Structured concurrency (3rd preview)
JEP 480 – Structured concurrency allows developers to treat groups of related jobs running on different threads as a single unit of work, simplifying error handling and cancellation, increasing reliability, and improving observability. This API supports a concurrent programming style that can eliminate common risks resulting from cancellation and shutdown, such as thread leaks and cancellation delays.
Scoped values (3rd preview)
JEP 481 allows the method to share immutable data with its callers both within the thread and with child threads. The use of scoped values is easier to reason about than thread-local variables. They also have lower space and time costs, especially when used with virtual threads (JEP 444) and structured concurrency (JEP 480).
ZGC: Default generational mode
JEP 474 switches the default Z Garbage Collector (ZGC) mode to generation mode. Feedback from the use of the generational ZGC introduced in JDK 21 as well as internal testing has confirmed that it performs significantly better than the non-generational ZGC in most use cases. This JEP also deprecates the non-generational ZGC mode with the intention of removing it in a future release of the JDK.
Notes on the Markdown document
JEP 467 allows using Markdown instead of just a combination of HTML and Javadoc @-tags to write comments in Javadoc documentation. The new format makes it easier to read and understand documentation in source form.
Deprecation of memory access method in sun.misc.Unsafe
JEP 471 – With the introduction of the foreign function and memory API (JEP 454) in JDK 22, a supported API for efficient access to external (foreign) memory was provided. Therefore, the future removal of methods in sun.misc.unsafe used for foreign memory access has been announced.
Click here for the release notes for Java 23 JDK.
Conclusion
Java 23 brings a number of improvements that simplify the work of developers and allow more efficient use of the platform. New features, such as language, performance and tooling enhancements, once again confirm that Java is the preferred choice for many developers.
Java SE 21 (LTS)
With the release of the next version of the Java JDK fast approaching, we decided to take a closer look at the Java new features on our blog. The target release date is scheduled for September 19, 2023. However, it is already possible to download this version in Early Access and start the first experiments.
Java 21 (after Java 17) is again a long-term support (LTS) release, which means that Oracle will provide free updates for at least five years, until September 2028, and extended paid support until September 2031.
Java 21 features, changes and improvements

Virtual threads
Virtual threads are lightweight threads that make it much easier to write, maintain and monitor high-performance, concurrent applications. This includes the ability to scale server applications written in thread-on-demand by making efficient use of hardware, the ability to easily migrate existing code that uses the lang.Thread API to virtual threads with minimal changes, and the ability to easily debug and profile virtual threads using existing JDK tools.
Virtual fibers were introduced in JDK 20 and JDK 19 and will be completed in JDK 21. With JDK 21, virtual threads now support local thread variables throughout runtime and are not allowed to create virtual threads without these variables. The guaranteed support for local thread variables ensures that many existing libraries can be used with virtual threads without modification.
Sequenced collections
Sequenced collections, or collections with ordering is another interesting new feature and JDK 21 introduces the design of collections with ordering and introduces interfaces for collections with defined ordering. Each collection has a clearly defined first, second and so on, down to the last element. Uniform APIs are provided for receiving first and last elements and for processing elements in reverse order. The motivation for this proposal is the fact that the Java collection framework does not have a collection type that represents a sequence of elements with a defined order. It also lacks a uniform set of operations that apply to these collections. These gaps have been a problem and a source of complaints. The proposal calls for defining interfaces for sequences of collections, sets and maps and including them in the existing hierarchy of collection types. All these new methods have predefined implementations.
Record patterns
Record patterns enable the deconstruction of record values. Record patterns and type patterns can be nested, enabling powerful, declarative, and composable data retrieval and processing. Design goals include extending pattern matching to destruct instances of record classes and adding nested patterns to enable data query composition. This feature has been developed in parallel with pattern matching for switch expressions.
Pattern matching for switch
This feature allows a switch expression/command to test itself against multiple patterns, each with a specific action, allowing complex data queries to be expressed safely and concisely. This feature was originally proposed in JDK 17, modified in subsequent versions, and was to be completed and modified in JDK 21 based on feedback and experience from Java developers. The main changes from previous versions of JEP include removing parentheses in patterns and allowing qualified enumeration constants, then increasing the safety of expressions and switch statements by requiring that all possible input values are covered. Another goal is to ensure that existing switch statements remain functional without modification and are executed with the same semantics.
String templates
This is a feature, in the form of an example in JDK 21, that complements the existing string literals and text blocks in Java by combining such text with embedded expressions and processors to produce specialized results. This language feature and API is intended to simplify the writing of Java programs by making it easy to express strings that contain values that are computed at runtime. It promises to improve the readability of expressions, increase program security, preserve flexibility, and simplify the use of APIs that accept strings written in languages other than Java. It also allows the development of non-string expressions created by combining text literals and embedded expressions.
Unnamed patterns and variables
This feature improves code readability and maintenance by allowing patterns to be created without specifying a component name or type. Unnamed variables can be initialized but are not used. The goal is to eliminate unnecessary nested patterns and identify unused variables.
Unnamed classes and instance main methods
This feature is focused on simplifying the writing of first Java programs, where students may not immediately understand language features designed for more complex projects. It allows you to create simple programs and gradually extend them with more advanced functionality.
Structured concurrency
Structured concurrency simplifies programming in a concurrent environment by using an API that manages groups of related tasks as units of work. This improves error management, which increases reliability and observability. This feature, previously tested in JDK 20 and JDK 19, is now supported as a sample API in the util.concurrent package.
Scoped values
The preview version of this feature, allows sharing immutable data between threads and components. Scoped values are preferred over thread local variables, especially when using a large number of virtual threads. This feature improves the readability and robustness of the code.
Prepare to disable dynamic agent loading
Disable dynamic agent loading – this change is aimed at improving the integrity of the JVM by alerting on loading agents dynamically while the application is running. The goal is to improve the balance between service changes and code integrity and to ensure that most tools are not affected by the change.
Key encapsulation mechanism API
This feature enables the use of algorithms to secure symmetric keys using public cryptography. The goal is to enable applications to use algorithms such as the RSA Key Encapsulation Mechanism (RSA-KEM) and the Elliptic Curve Integrated Encryption Scheme (ECIES) in a variety of protocols and cryptographic schemes.
Generational ZGC
This feature is aimed at improving application performance by using separate generations for young and old objects. Generational ZGC enables more efficient collection of young objects and results in lower memory consumption and a lower garbage collection burden (collecting unnecessary allocated memory).
Foreign function & memory API
This enables Java programs to interoperate with code and data outside the Java runtime. It allows calls to external libraries and secure memory access, replacing JNI (Java Native Interface).
Vector API
This API allows calculations to be performed vectorially, resulting in better performance than scalar calculations. The goal is to provide a simple and reliable solution for vector computation on supported architectures.
Deprecate the Windows 32-bit x86 Port for Removal
This change is aimed at removing the 32-bit port for Windows x86 in a future release. Windows 10, the last Microsoft operating system to support 32-bit mode, ends its lifecycle in October 2025.
In addition to these features, JDK 21 is also in the process of changing the naming of network interfaces in Windows. An experimental “compact object headers” feature is also planned to reduce the size of object headers in the JVM, thereby reducing memory footprint.
If you are interested in the new features of Java JDK 21 and would like to learn more about them, visit the official OpenJDK website.
Java SE 20
Oracle announced 21. March 2023 availability of its latest version of the world’s most popular programming language and development platform. In this article, we will focus on some of the most significant news.

Java SE 20 (Oracle JDK 20) delivers thousands of performance, stability and security improvements, including platform enhancements that will help developers increase productivity and drive innovation and growth in their organizations. It’s been more than 25 years since Java enabled developers to design and build new generations of robust, scalable, and secure applications.
Oracle JDK 20 is not a long-term support (LTS) release, so it will receive updates only until it is replaced in six months by JDK 21.
The last LTS Java release is still Oracle JDK 17 (released on 14 September 2021). However, Oracle has announced plans to reduce the time between LTS releases from three years to two years, so JDK 21 is scheduled to be the next LTS in September 2023.
The amount of change over time in JDK releases hasn’t changed much, but under the six-month pressure of releasing new versions, the pace of delivering new functionality and production-ready enhancements has increased sharply. Instead of Oracle making tens of thousands of fixes and delivering nearly a hundred JEPs (JDK enhancement proposals) every few years, as they used to do with major releases, enhancements are delivered in more modest releases on a more predictable six-month schedule. Changes range from significant new functionality, to small improvements, to routine maintenance, bug fixes and documentation improvements. Each change is represented by a separate commit and issue in the JDK error system.
New in the Java 20 JDK
The Java 20 JDK contains seven JDK Enhancement Proposals (JEPs) that aim to increase developer productivity, improve the Java language, and enhance the performance, stability, and security of the platform. These features include virtual threads, vector API design, structured concurrency, scoped values, foreign function and memory APIs, record patterns, and pattern matching for commands and switch expressions.
Virtual threads
Virtual threads are lightweight threads that reduce the effort required to write, maintain and debug high-performance concurrent applications. They are instances of the java.lang.Thread class, but they are not bound to a specific operating system thread. When code running in a virtual thread calls a blocking I/O operation, the Java Runtime suspends the virtual thread until it can recover it. The operating thread associated with the suspended virtual thread is now free to perform operations for other virtual threads.
Virtual threads are useful for running tasks that spend most of their time blocking, often waiting for I/O operations to complete. However, they are not designed for long-running, processor-intensive operations.
Vector API proposal
The vector API design is a new feature in the Java 20 JDK that introduces an API for expressing vector computations that reliably compile to optimal vector instructions on supported CPU architectures, achieving performance superior to equivalent scalar computations.
The goal is to provide a clear and concise API capable of expressing a wide range of vector computations consisting of sequences of vector operations, looped and possibly flow-controlled. It should be possible to express a computation that is generic with respect to the size of the vector or the number of orbits per vector, thus allowing portability of such computations across hardware supporting different vector sizes.
Structured concurrency
This is a new feature in the Java SE 20 JDK that provides an API to simplify the programming of multithreaded applications and treat multiple tasks running in different threads as a single unit of work. Error handling and fiber cancellation are simplified, which improves reliability and increases observability.
The only change from the concept in JDK 19 is that the StructuredTaskScope class has been updated to support inheritance of scoped values by threads created in a task scope.
Scoped values
Scoped values are a new feature in the Java 20 JDK that allows developers to store and share immutable data within and between threads. This new API is introduced in the Java 20 JDK as an incubator feature proposed in JEP 439.
The Java 20 JDK introduces a new class jdk.incubator.concurrent.ScopedValue<T>, which represents a scoped value as a key-value pair. Basically, a scoped value is a value that is set only once and is available for reading for a limited time in a thread. Scoped values provide data sharing without the use of method arguments.
Foreign function and memory API
This new feature in the Java 20 JDK allows Java programs to interact with code and data outside the Java runtime environment. By efficiently calling foreign functions (code outside the Java Virtual Machine [JVM]) and safely accessing foreign memory (memory not managed by the JVM), this feature allows Java programs to call native libraries and process native data without the need for the Java Native Interface. This improves usability, performance and security.
Record patterns
This enhancement extends the Java language by allowing users to nest record patterns and type patterns to create a powerful, declarative, and composite form of data navigation and processing. This helps increase developer productivity by allowing them to extend pattern matching to enable more sophisticated data queries.
Pattern matching for switch statements and expressions
This allows developers to use patterns in switch conditions. It provides greater flexibility and expressiveness compared to using constants.
Conclusion
In addition to bug fixes, the new Java SE 20 JDK release includes seven JDK enhancements that improve developer productivity, enhance the Java language, and improve the performance, stability, and security of the platform.
Java latest version download here: Java SE 20 JDK.
Java SE 17 (LTS)
Until March 2022, the latest version of Java 17, which brings a new rendering pipeline for MacOS systems, port support for Apple’s latest M1 chip, and support for sealed classes. There are also language improvements and the removal of ahead-of-time and just-in-time complications.
Source: java SE 17
Java SE 16
Version 16 was released in March 2021 and brought one major change, which was the migration of OpenJDK to Git. The OpenJDK source code has been migrated from Mercurial to Git. The reason was the size of the metadata files, better tools and hosting.
Source: java SE 16
Java SE 15
Java SE 15 was released in September 2020 and brought with it three major updates:
Text blocks as standard
Text blocks, which were introduced as a preview in the Java 13 environment, have become a language standard.
Sealed class
The public, protected and private access modifiers provide very coarse control. The keywords sealed, non-sealed and permits allow the developer to play with the inheritance hierarchy. The goal of sealed classes is to allow individual classes to declare which types can be used as subtypes. This also applies to interfaces and determining which types can implement them.

In this example, we have declared an abstract class called Person. We also specified that the only classes that can extend it are Employee and Manager. Extending a sealed class is done the same way as in Java today using the extends keyword:

Any class that extends a sealed class must itself be declared sealed, non-sealed, or final. This ensures that the class hierarchy remains finite and is known to the compiler.
Hidden classes
The goal of hidden classes is to allow you to create classes that are not visible. This means that they cannot be associated with other classes, nor can they be discovered by reflection. Classes such as these usually have a short life cycle, so they are designed to be mainly efficient. They are especially useful for developers working with the JVM.
Source: java SE 15
Java SE 14
Java SE 14 was released in March 2020, bringing up to four major enhancements:
Switch as standard
Introduced as a preview in Java 12 and enhanced in version 13, the switch expression has become a language standard.

NullPointerException improvement
NullPointerException hasn’t had much meaningful value in the past. The reason was that it could only detect that a certain value was zero in a given set. However, everything is different in the new version. The function has been extended and developers will finally know which variable caused the exception.
Java records
Records were introduced to reduce repetitive standard code in the POJO data models. They simplify day-to-day development, increase efficiency and significantly minimise the risk of human error. For example, a data model for a user with an ID and password can be simply defined as:

In this case, the new record keyword was also used, which automatically adds constructor methods, getters, equals, hashCode and toString.
Pattern matching for instanceof
Version 14 introduced pattern matching to simplify the code. Without the new feature, the code would look like this:

However, thanks to the new version of Java, the code looks much simpler and shorter:

Source: java SE 14
Java SE 13
Java 13 was released in September 2019. The update came with two major improvements:
Text blocks
The new text block feature made it easier for developers to read multi-line text. It uses three quotes, similar to Python and Groovy.

In addition, all the functions of the String class are available.

Enhancements to the switch expression
Java 13 enhances the switch expression from version 12 with the yield keyword. You can use yield to return values from a switch expression.

Source: java SE 13
Java SE 12
Version 12 was released in March 2019 and came with only one significant improvement. It was an alternative switch entry. The following example compares the old and new notation of switch. The code distinguishes between weekdays and weekends.


The code in the new notation looks much cleaner and shorter. The new switch form also removes the need for break keywords. This means that when the code finds the first match, it stops working. Another difference is that a variable can be assigned a value directly from a switch expression.
Source: java SE 12
Java SE 11 (LTS)
Java 11 was the most used version in 2021, according to Snyk’s annual survey. Up to 61.5% of respondents used it. Only 12% had upgraded to the latest version, which was Java 15 at the time of the survey.
Also interesting were the answers to the question what are the reasons that people have not switched to a newer version. Most agreed that they were unable or unwilling to migrate Java every 6 months. Others, around 51%, say they do not need changes because their current environment is working well.
Other reasons given by respondents for staying with older versions include:
- the high cost of migration,
- reluctance of customers to migrate,
- the new version has no special improvements,
- application servers or libraries do not support the latest versions.
The 2020 survey, on the other hand, found that the strategy of most developers (55%) is to stick to long-term releases. Despite this, up to 22% of respondents say they plan to decide whether or not to innovate. They want to see if the newly introduced functions are important enough to justify migration.
Java SE 11 was released six months after version number 10, in September 2018. It brought two major changes:
Running Java files
The main change in this version is that developers no longer need to explicitly compile the ava source files using the javac command.

Instead, you can run the file directly with the java command.

Using local variable syntax
Java 11 has support for using local variable syntax in lambda parameters. The function can be used to apply modifiers to local variables, for example, to define an annotation.

Source: java SE 11
Java SE 10
Java SE 10 was released by Oracle in March 2018. It brought two important changes for developers:
OpenJDK
To make the Java community more Java friendly, Oracle has started promoting OpenJDK binaries as the primary JDK for the future. The problem is that if you want to get extended support for older versions of Java, for example, you have to pay for the services.
Var variable
The var variable is not new, as it exists in other programming languages. Its main advantage is that it reduces the eloquence of the tongue. In practice, this means that you can avoid long object names or typing the same name twice.
However, developers may wonder what the difference between var and Object is. The var keyword means that you want the compiler to detect the type itself. On the other hand, you use Object to convert your object instance to the Object type. This means that although you can use the general methods of the Object class, you cannot use its class-specific methods. This will create a compilation error.
Source: java SE 10
Java SE 9
Java SE 9 was released in September 2017 and brought with it several changes. But not all of them were significant and important. These are the top three:
Modularity – Project Jigsaw
The most significant change in the Java 9 environment was the modularity system, which was named the Project Jigsaw. A module is a group of code characterized by certain properties. The modularity feature breaks down a programming language into smaller models to:
- Shading,
- reducing conflicts between versions,
- adding encapsulation,
- better security,
- higher performance,
- customized runtime JDK with smaller size.
To create a new model, you need the module-info.java file in your src.main.java directory. In it you can define your module requirements.
Private methods in Java interfaces
Another Java 9 feature is the ability to write private and static methods in interfaces to avoid redundant code.

Java JShell command line tool
Oracle has developed a new REPL tool called JShell. REPL stands for Read – Evaluate – Print – Loop. As its name suggests, it is used to run commands, create variables, classes, methods and allows you to quickly test them. It’s great for testing small snippets of code that would otherwise require creating a new class using the main method.
JShell can be found in the <JAVA_HOME> / bin folder and you can run it by typing jshell at the command line and start writing code immediately.

Interactive Java jshell comes with history and autocomplete. It also provides features such as saving and loading from files and all or some lines of code:

Source: java SE 9