Java JDK: Overview of versions, differences between LTS, SE, JRE and Java 24

We bring you an overview of Java versions, a comparison of Java JDK, SE and LTS releases, as well as a summary of the most important changes in the latest versions – including Java 24, which once again pushes the boundaries of the language a step further. This way, you will gain a clear picture of the main differences between the versions, what new features they bring, and what to watch out for during migration.

Java JDK version
Java JDK version

V článku sa dozvieš:

    Java versions JDK, SE, LTS and release frequency

    Java has been evolving continuously for more than two decades, and in order to keep up with modern development requirements, it has adopted a six-month 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.

    For companies and developers it is crucial to understand the difference between LTS versions (Long-Term Support), which ensure stability and long-term support, and non-LTS versions, which are intended more for testing new features and preparing for future LTS releases.

    Java versions 1-21
    Overview of Java version 1-21, source Wikipedia license CC BY-SA 4.0.
    java versions 22-25
    Overview of Java versions 22-25, source Wikipedia licence CC BY-SA 4.0.

    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), as well as a debugger, standard API libraries, documentation, and various tools for managing and testing applications. JDK is therefore essential for every developer, as it provides a complete environment for writing, compiling, running and debugging code.

    Okrem základných nástrojov ponúka JDK aj rôzne pomocné utility, ako napríklad javadoc na generovanie dokumentácie priamo zo zdrojového kódu alebo jlink na vytváranie vlastných runtime obrazov Javy. It is important to distinguish it from JRE (Java Runtime Environment), which is only used to run ready-made applications. While JRE is used by end users, JDK is primarily intended for developers – without it, it would not be possible to create or test applications in Java.

    Java SE (Java Platform, Standard Edition)

    Java SE (Java Platform, Standard Edition) is the core edition of the Java platform, defining the standardised API, syntax and behaviour of the language. It includes key libraries and packages, such as Collections, Concurrency, I/O, Networking, Security, and XML processing. Thanks to Java SE, a common foundation exists on which all Java applications and frameworks are built – from simple desktop programmes to large-scale enterprise solutions.

    Java SE is not a development tool like JDK, but rather a “standard” and specification of what each version of Java must contain. It is the official definition of the language that all Java implementations (e.g. OpenJDK) must follow. For developers, it provides the assurance that code written according to Java SE will work in any environment compatible with this standard.

    JRE (Java Runtime Environment)

    Java Runtime Environment (JRE) is an environment intended for running applications written in Java. It contains the Java Virtual Machine (JVM), which handles the translation and execution of bytecode, as well as the basic libraries required for programmes to run. Unlike JDK, it does not provide development tools – its sole purpose is to ensure that a finished application can run on a computer or server.

    JRE is therefore suitable for end users or production environments where applications are only run and not further developed. A developer usually needs only JDK (which automatically includes JRE), while JRE on its own is used by those who only run applications.

    Java LTS (Long-Term Support)

    Java LTS (Long-Term Support) represents Java versions that have guaranteed long-term support from Oracle or other vendors (Adoptium, Red Hat, etc.). Each LTS version is released approximately once every three years and provides companies with stability, security patches and bug fixes for 8 or more years. That is precisely why LTS releases are the most common choice for enterprise projects, where reliability and minimal risk in operation are crucial.

    In contrast to non-LTS versions, which are supported for only 6 months and serve mainly for testing new features, LTS versions function as stable milestones in the history of Java. Developers and companies usually migrate directly from one LTS to the next (e.g. from Java 11 to 17 or 21), thereby avoiding problems associated with short-term releases. LTS therefore represents a safe foundation for long-term projects and production environments.

    Differences between Java JDK, SE, LTS, JRE

    Comparison table: LTS vs. non-LTS versions of Java + JDK, SE, 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 javac compiler, tools, debugger, documentation, libraries Platform and API defined by the standard (JLS, JVM, libraries) Includes JVM + core libraries, no development tools
    Release Every 3 years (e.g. Java 11, 17, 21) Every half year (e.g. Java 12, 13, 14) Distributed with every version of Java (LTS and non-LTS) Defines what each version of Java “must have” Tied to a specific version of Java, released with the JDK
    Stability Very stable, recommended for companies and production More experimental, bring new features faster Provides all development tools for working with Java Contains core APIs (Collections, Streams, IO, Concurrency, etc.) Stable environment for running applications
    Target group Corporations, enterprise solutions, long-term projects Developers, testing new features Programmers and development teams The entire Java community (standardisation) End users and environments where applications are only run
    Risk Minimal, long-term fixes and security patches Higher – possible feature removal in next version 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, etc. JDK 11, JDK 16, JDK 24… Java SE 9, SE 18, SE 25, etc. JRE 8, JRE 11, JRE 17, etc.

    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 other hand, non-LTS versions are short-term – they are released every half year and bring faster innovations. Developers use them for testing new features, but in production it is usually the next LTS that is adopted.

    JDK (Java Development Kit) is a package of tools that you get with every version of Java and which directly serves 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) → tools for developers (compiler, debugger, libraries)
    • Java SE (Standard Edition) → core standard and API on which the whole of Java is based

    So, if you are considering which version to choose:

    • For a long-term project, go 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 adapting the existing code.

    Main steps of migration:

    1. Project analysis
      • Check what libraries and frameworks you are using.
      • Verify if they are compatible with the target version of Java.
    2. Checking removed and deprecated APIs
      • In new versions some functions are marked as deprecated and later completely removed.
      • Typical examples: old security algorithms, internal API sun.
    3. Compatibility testing
      • Run existing tests on the new JDK version.
      • Monitor warnings and errors during compilation.
    4. Adjusting the build and CI/CD pipeline
      • Update build tools (Maven, Gradle).
      • Make sure the CI/CD pipeline is running on the correct JDK version.
    5. Gradual transition
      • For large projects it is advisable to switch from LTS to LTS (e.g. from 11 → 17 → 21).
      • This way you avoid inter-version problems and maintain stability.
    6. Performance and regression testing
      • Test your application under load to detect possible slowdowns or memory leaks.

    Most common problems during migration:

    • Unsupported libraries – older dependencies may not work on the new JDK.
    • Removed APIs – if the project uses internal JDK APIs, this may cause errors.
    • Security changes – stricter TLS/SSL settings may block older connections.

    The safest approach is always to migrate to the latest LTS version, test the application, and then deploy it into production. Non-LTS versions are suitable for experiments, but not for long-term operation of applications.

    Next, we will go through the changes and improvements in individual Java versions in detail.

    Java SE 24

    Java 24 has brought a new version, JDK 24, with a symbolic 24 enhancements to the language, API, platform performance, stability, and security. We have not had such a feature-packed release in a long time. So let us not waste time and let us go through them one by one.

    Java JDK 24 brings several changes and improvements

    The new version, Java 24, was released by Oracle on 18 March 2025. The complete developer package, the Java Development Kit 24 (JDK 24), for this version of Java brings numerous improvements for programmers.

    Recommend

    We recommend you…

    Java 24, including the release notes, is available for download at this link.

    Similar to previous versions of Java, Java 24 is the collective effort of many contributors – whether individuals or organisations of the OpenJDK community. While the number of changes in JDK releases has remained roughly the same for several years, during the last six-month cycle the pace at which new features and improvements reach production has accelerated significantly.

    Evolution of the number of new features in Java JDK versions 8 to 24.
    Overview of Java enhancements (JEPs) over the last 11 years (source: Oracle)

    The changes in JDK 24 range from major new features through minor enhancements to routine maintenance, bug fixes, and documentation improvements. Each change for a given ticket is represented by a separate commit into the JDK Bug System repository.

    Did you know that…

    …31,187 issues were resolved between Java 11 and Java 24? Of these, 22,107 (approximately 70%) were resolved by Oracle employees, while 9,080 (approximately 30%) were resolved by individual developers working either independently or for other organisations. Of the 2,463 JIRA issues marked as fixed in Java 24, Oracle completed 1,657 (approx. 67%), while other members of the Java community resolved 806 (approx. 33%).

    JDK 24 introduces 24 improvements that are significant enough to merit their own JDK Enhancement Proposals – JEPs – including 8 feature previews and 1 incubator feature.

    Language features of Oracle JDK 24

    Primitive types in patterns, instanceof, and switch (preview 2)

    JEP 488: Extends pattern matching to allow type patterns with primitive types in all contexts, while also enhancing the instanceof and switch operators with support for all primitive types, including safe testing and conversions. This achieves a unified, more expressive language for processing values and types without manual casting or range checks.

    Flexible constructor bodies (preview 3)

    JEP 492: Allows the insertion of ordinary statements before the explicit invocation of super(…) or this(…) in the constructor body, with such statements being able to initialise fields and validate arguments, but not use the not-yet-constructed object. This introduces a more natural model of validation and data preparation before creating the superclass, thereby simplifying and clarifying constructor code.

    Module import declarations (preview 2)

    JEP 494: Introduces a new syntactic construct import module M;, which with a single command imports all public top-level classes and interfaces exported by module M (including transitive dependencies). This eliminates the need for many import … .* statements and significantly simplifies the reuse of modular libraries in all types of projects.

    Simple source files and instance main methods (preview 4)

    JEP 495: Brings an easier way to create small Java programmes: it allows writing executable programmes without a dedicated class and without the boilerplate public static void main(String[] args), supports instance main methods (with no parameter and no modifiers), and simple source files with automatic imports of basic console I/O methods and the entire java.base module. This reduces the learning curve while still maintaining the possibility of a smooth transition to full-fledged programmes.

    Oracle JDK 24 libraries

    Class-file API

    JEP 484: Introduces a standardised API (java.lang.classfile) for parsing, generating, and transforming .class files according to the format defined by the JVM specification. The aim 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 possibility of defining custom intermediate operations (Stream::gather), which enable tailored transformations of stream elements (one-to-one, one-to-many, many-to-many) with full support for parallelisation and without the need for external data collectors. This simplifies expressive and efficient processing of data pipelines.

    Scoped values (preview 4)

    JEP 487: Introduces a new type ScopedValue for sharing immutable data within a method, its calls, and newly created threads as a simpler and more efficient alternative to ThreadLocal. It has lower spatial and temporal overhead and is particularly suitable when using virtual threads.

    Vector API (9th incubator)

    JEP 489: Provides a platform-neutral, high-performance interface for expressing vector computations, which are mapped at runtime to native SIMD instructions on supported CPUs. As a result, developers can achieve better performance than with equivalent scalar computations, which are increasingly used in AI workloads.

    Structured concurrency (preview 4)

    JEP 499: Makes it possible to manage groups of related tasks as a single unit of work through a new API, simplifying error handling, cancellation, and observability in concurrent applications. This concept helps prevent “thread leaks” and improves reliability and readability of code.

    Oracle JDK 24 security libraries

    Key derivation function API (preview)

    JEP 478: Introduces a new API javax.crypto.KDF for generating and expanding 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 (e.g. in Hybrid Public Key Encryption or TLS 1.3) and provides an interface for extensibility to additional KDF implementations.

    Quantum-resistant module-lattice-based key encapsulation mechanism

    JEP 496: Delivers an implementation of ML-KEM, a quantum-resistant KEM scheme standardised in NIST FIPS 203. It extends KeyPairGenerator, KEM, and KeyFactory with parameter sets ML-KEM-512, ML-KEM-768, and ML-KEM-1024, thereby enabling applications to securely exchange symmetric keys resistant to attacks from future quantum computers.

    Quantum-resistant module-lattice-based digital signature algorithm

    JEP 497: Adds support for ML-DSA, a quantum-resistant digital signature algorithm (FIPS 204). It implements KeyPairGenerator, Signature, and KeyFactory for three parameter sets ML-DSA-44, ML-DSA-65, and ML-DSA-87, which enables authentication and verification of data integrity with resistance to quantum attacks.

    Oracle JDK 24 tools

    Linking run-time images without JMODs

    JEP 493: Enables the creation of runtime images via the jlink tool without JMOD files, reducing the JDK installation size by up to 25% and simplifying module management in cloud and container environments.

    Oracle JDK 24 runtime performance improvements

    Compact object headers (experimental)

    JEP 450: Reduces the size of Java object headers from 96–128 bits to 64 bits on 64-bit platforms, saving memory and improving data locality in the cache. Activated with VM options:
    -XX:+UnlockExperimentalVMOptions -XX:+UseCompactObjectHeaders.

    Late barrier expansion for G1

    JEP 475: Moves the expansion of memory barriers in G1 GC from the early stages of C2 compilation to later ones, reducing compilation time and simplifying implementation, while maintaining the performance of the generated code.

    Ahead-of-time class loading & linking

    JEP 483: Improves JVM startup by saving loaded and pre-linked classes into a cache during one run, which HotSpot uses at the next startup, thereby reducing initial startup time.

    ZGC: Remove the non-generational mode

    JEP 490: Removes the Non-Generational mode for the Z Garbage Collector (-XX:+ZGenerational), reducing code complexity and making generational ZGC the primary mode, which is more suitable for most deployments.

    Synchronise virtual threads without pinning

    JEP 491: Improves the scalability of synchronised blocks when using virtual threads by releasing the platform thread upon blocking instead of holding it, thus increasing the number of serviced virtual threads.

    Oracle JDK 24 source code

    Generational Shenandoah (experimental)

    JEP 404: Introduces an experimental generational mode into Shenandoah GC, which improves sustainable throughput, resilience to sudden load, and memory utilisation by dividing 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: Runtime warnings have started being issued when calling JNI and the Foreign Function & Memory API, to prepare developers for an upcoming release that will reduce or prohibit implicit support of native interaction. JNI remains possible, but with clear warnings and consistent behaviour before moving to stricter restrictions.

    Remove the Windows 32-bit x86 port

    JEP 479: Removes source code and build scripts for the Windows 32-bit x86 port (deprecated in JDK 21), eliminating all specific paths and tests for this port. After Windows 10 32-bit support ends (EOL October 2025), JDK build and testing infrastructure will be simplified.

    Permanently disable the security manager

    JEP 486: The platform specification is updated so that the Security Manager can no longer be enabled in any way, and its API will not be referenced in code, thereby removing an obsolete and costly security mechanism, which was deprecated in Java 17.

    Warn upon use of memory-access methods in sun.misc.Unsafe

    JEP 498: At the first call of any memory-access API in sun.misc.Unsafe, the JVM issues a runtime warning. These methods were deprecated in JDK 23 and are intended to be replaced by standard cryptography 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 its complete removal in JDK 25. After removal, only the agnostic Zero port will remain for 32-bit architecture platforms.

    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 today’s technological trends. The release of Java 23 with numerous enhancements once again demonstrates that careful planning and predefined, well-observed deadlines contribute to Java and its ecosystem becoming the preferred platform for modern software development for many developers worldwide.

    Overview of Java enhancements (JEPs) over the last 10 years

    SOURCE: inside.java/2024/09/17/jdk-23-available/
    SOURCE: inside.java/2024/09/17/jdk-23-available/

    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 (on average around 10), but this is due to the regular six-month release cycle, which despite the relatively short preparation time, ranges from new language features, to small improvements to existing functionality, to bug fixes and documentation updates.

    Each change to a ticket is represented by a separate commit to the JDK Bug System repository. Interestingly, 28,724 issues were resolved between Java 11 and Java 23. Of these, 20,450 (approximately 71%) were completed by Oracle employees, while 8,274 (approximately 29%) were resolved by individual Java programmers working either independently or for other organisations.

    Primitive types in patterns, instanceof and switch (preview)

    This change (JEP 455) will remove several restrictions that exist when using primitive types in pattern matching. Code handling primitive types and object types can be simplified when no special adjustments are needed and both types can be handled in the same way. Allowing
    instanceof
    to accept primitives further reduces code for common cases, as it can now automatically handle conditional casts – where it is necessary to check the value to ensure it is valid for the target type.

    Module import declarations (preview)

    JEP 476 – allows developers to import all packages exported by a module with a single command. This simplifies the reuse of modular libraries without requiring the imported code to be in the module itself. Thanks to this feature, beginners can use third-party libraries and core Java classes without needing to learn where they are located within the package hierarchy.

    Implicitly declared classes and instance main methods (third preview)

    JEP 477 – This will allow beginners to write their first Java programmes without having to first understand features intended for larger and more complex applications. Simple programmes can use simplified declarations and can, if necessary, be seamlessly extended with more advanced features as required. Experienced developers can also enjoy concise writing of small programmes.

    Flexible constructor bodies (second preview)

    JEP 482 – By allowing certain statements in constructors to appear before an explicit constructor invocation, that is, super(…) or this(…), developers gain the freedom to better express constructor behaviour. The more natural placement of logic provided by this feature removes the need to incorporate some checking and initialisation logic into helper static methods and auxiliary constructors. For example, if a constructor can validate received arguments before invoking the superclass constructor, it will fail fast and thus avoid creating an unnecessary superclass instance when the arguments are invalid.

    Class-File API (second preview)

    JEP 466 – this JEP proposes an API for analysing, 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 every release, it will ease the tension caused by Java’s adoption of the six-month release cycle and frameworks that manipulate class files, which are updated with each release to ensure rapid adoption of new versions. Once completed, this functionality should free the JDK itself from its dependency on the third-party ASM library.

    Vector API (eighth incubator)

    JEP 469 – allows Java developers to express vector computations that are reliably compiled at runtime into optimal vector instructions on supported CPU architectures, achieving better performance than equivalent scalar computations. There are no differences from the seventh incubation of this feature in JDK 22. It is expected that this API will continue to return in incubation form, with at most small changes, until the necessary features from Project Valhalla become available.

    Stream gatherers (second preview)

    JEP 473 – enhances the Stream API to support custom intermediate operations. This will allow stream pipelines to transform data in ways not easily achievable with existing built-in intermediate operations. Stream gatherers provide the same flexibility for intermediate operations as collectors do for terminal operations. This enhancement introduces five built-in gatherers.

    Structured concurrency (third preview)

    JEP 480 – structured concurrency enables developers to treat groups of related tasks running in different threads as a single unit of work, simplifying error handling and cancellation, increasing reliability, and improving observability. This API supports a style of concurrent programming that can eliminate common risks arising from cancellation and shutdown, such as thread leaks and cancellation delays.

    Scoped values (third preview)

    JEP 481 – will allow a method to share immutable data with its callers within a thread and with child threads. Using scoped values is easier to reason about than thread-local variables. They also have lower space and time costs, especially when used together with virtual threads (JEP 444) and structured concurrency (JEP 480).

    ZGC: Generational mode by default

    JEP 474 – will switch the default mode of the Z Garbage Collector (ZGC) to generational mode. Feedback from the use of generational ZGC, introduced in JDK 21, as well as internal testing, confirmed that in most use cases it performs significantly better than non-generational ZGC. This JEP also deprecates the non-generational mode of ZGC with the intention to remove it in a future JDK release.

    Markdown documentation comments

    JEP 467 – allows the use of Markdown instead of only 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.

    Proposal to remove 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 was provided for efficient access to external (foreign) memory. Therefore, the future removal of methods in sun.misc.unsafe used for foreign memory access was announced.

    Here you can find the release notes for Java JDK 23.

    Conclusion

    Java 23 brings a number of enhancements that simplify developers’ work and enable more efficient use of the platform. New features, whether in language, performance, or tools, once again confirm that Java remains 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 once again a long-term support (LTS) version, 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

    Java JDK 21 features
    Java JDK 21 features

    Virtual threads

    Virtual threads are lightweight threads that significantly simplify writing, maintaining, and observing high-performance concurrent applications. They include the ability to scale server applications written in a thread-per-request style by efficiently using hardware, the possibility of easy migration of existing code that uses the lang.Thread API to virtual threads with minimal changes, and the ability to debug and profile virtual threads easily using current 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 were a problem and a source of complaints. The proposal requires the definition of interfaces for sequenced collections, sets, and maps and their inclusion in the existing type hierarchy of collections. 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 immutable data to be shared between threads and components. Scoped values are preferred over thread-local variables, especially when using a large number of virtual threads. This feature improves code readability and robustness.

    Prepare to disallow the dynamic loading of agents

    The disallowance of dynamic agent loading – this change aims to improve the integrity of the JVM by alerting to agents being dynamically loaded during application runtime. The goal is to improve the balance between serviceability changes and code integrity and to ensure that most tools are not affected by this 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 using separate generations for young and old objects. Generational ZGC enables more efficient collection of young objects and brings lower memory usage and reduced garbage collection overhead.

    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 focuses on the removal of the 32-bit port for Windows x86 in a future release. Windows 10, the last Microsoft operating system with support for 32-bit mode, reaches its end of life 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, we recommend visiting 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.

    An overview of the number of releases of the Java JDK and the time interval between them.
    An overview of the number of releases of the Java JDK and the time interval between them. SOURCE: blogs.oracle.com

    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, therefore it will only receive updates until it is replaced by JDK 21 in six months.

    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 number of changes over time in JDK releases has not changed much, but under the six-month pressure of releasing new versions, the pace of delivering new functionality and production-ready enhancements has sharply increased. 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 with major releases, enhancements are now delivered in smaller releases on a more predictable six-month schedule. The changes range from major new functionality, through minor improvements, to routine maintenance, bug fixes, and documentation updates. Each change is represented by a separate commit and issue in the JDK bug system.

    What is new in 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 proposal is a new feature in Java 20 JDK that introduces an API for expressing vector computations that reliably compile to optimal vector instructions on supported CPU architectures, thereby 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 Java SE 20 JDK that provides an API to simplify programming multithreaded applications and handling multiple tasks running in different threads as a single unit of work. Error handling and cancellation of threads are simplified, which improves reliability and enhances observability.

    The only change from the concept in JDK 19 is that the StructuredTaskScope class has been updated to support the inheritance of scoped values by threads created in the 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

    The new Java SE 20 JDK release, in addition to bug fixes, brings seven JDK Enhancement Proposals to increase developer productivity, improve the Java language, and enhance the performance, stability, and security of the platform.

    You can download it here: Java SE 20 JDK download.

    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 Java 13, became 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.

    Code - Inheritance hierarchy using sealed classes
    Sealed classes allow the declaration of types that can be defined as subtypes in each class.

    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:

    Code - Sealed class extension in Java SE 15
    Use extends to extend sealed classes in the current version of Java and in SE 15.

     

    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 aim of hidden classes is to enable the creation of classes that are not visible. This means that they cannot be linked by other classes, nor can they be discovered using reflection. Classes like these usually have a short lifecycle, which is why they are designed to be mainly efficient. They are particularly useful for developers working with the JVM.

    Source: Java SE 15

    Java SE 14

    In March 2020, version Java SE 14 was released and brought as many as four significant improvements:

    Switch as a standard

    The switch expression, which was introduced as a preview in Java 12 and enhanced in version 13, became a language standard.

    Code – Switch as a language standard in Java SE 14
    Java SE 14 turned the original term switch into a language standard in programming.

    Improvement of NullPointerException

    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 boilerplate code in POJO data models. They simplify everyday 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 easily be defined as:

    Code - New records feature in Java SE 14
    Java 14 introduced POJO records to reduce repetitive standard code in data models.

    In this case, the new keyword record was also used, which automatically adds constructor methods, getters, equals, hashCode, and toString.

    Pattern matching for instanceof

    Version 14 introduced pattern matching to simplify code. Without the new feature, the code would look like this:

    Code - Pattern matching using the instanceof function in Java 14
    The old instanceof feature notation for pattern matching was complex.

    Thanks to the new version of Java, however, the code looks much simpler and shorter:

    Code - Improved instanceof function in Java 14
    A new feature of Java 14 has simplified the writing of the instanceof expression.

    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 blocks feature allowed developers to more easily read multi-line texts. It uses three quotation marks, similar to Python and Groovy.

    Code - New text block feature in Java SE 13
    Java 13 introduces a new text block feature that uses three quotes like Python and Groovy.

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

    Code - Functions of class String in Java SE 13
    In Java SE 13 you also have all the functions of the String class.

    Improvements of the switch expression

    Java 13 improves the switch expression from version 12 with the yield keyword. With yield, values can be returned from a switch expression.

    Code - Improved switch expression from version 12 in Java SE 13
    Java SE 13 offers an improved switch expression from version 12.

    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 expression syntax. The following example compares the old and new switch expression syntax. The code distinguishes between working days and weekend days.

    Code - old switch syntax in Java SE 12
    Java 12 improved the old switch expression syntax.
    Code - Alternative syntax for switch in Java 12
    Java SE 12 introduced a new alternative switch expression syntax.

    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)

    According to the annual survey by the company Snyk, Java 11 was the most widely used version in 2021. As many as 61.5% of respondents were using it. Only 12% had updated the language to the latest version, which at the time of the survey was Java 15.

    The answers to the question about the reasons why people did not upgrade to a newer version were also interesting. Most agreed that they were not able or willing to migrate Java every 6 months. Others, about 51%, said that they did not need the changes because their current environment was working well.

    Other reasons why survey participants remain on older versions include:

    • High migration costs
    • Unwillingness of customers to migrate
    • The new version does not have any special improvements
    • Application servers or libraries do not support the latest versions

    From the 2020 survey, it also emerged that the strategy of most developers (55%) is to stick to long-term releases. Nevertheless, as many as 22% of respondents stated that they plan to decide whether or not to upgrade. They want to find out whether the newly introduced features 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 key change in this version is that the programmer does not need to explicitly compile Java source files with the javac command.

    Code to run Java files without compiling source files
    In Java 11, you no longer need to explicitly compile ava source files using the javac command.

    Instead, the file can be run directly using the java command.

    Code – Direct running of Java files in SE 11.
    Direct running of Java files in SE 11.

    Use of local variable syntax

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

    Code - Using Local Variable Syntax in Java SE 11
    Java SE 11 allows the use of local variable syntax in lambda parameters.

    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.

    The var variable

    The var variable is nothing new, as it also exists in other programming languages. Its main advantage is that it reduces verbosity of the language. In practice, this means that with it you avoid long object names or writing the same names twice.

    However, programmers may ask what the difference is between var and Object. The var keyword means that you want the compiler to infer the type by itself. On the other hand, with Object you cast your object instance to the Object type. This means that although you can use general methods of the Object class, you cannot use your 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 – Jigsaw Project

    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:

    • Shadowing
    • Reducing version conflicts
    • Adding encapsulation
    • Higher security
    • Higher performance
    • Customised runtime JDK with a 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 feature of Java 9 enables writing private and static methods in interfaces in order to avoid redundant code.

    Private and static methods code in Java 9
    Java 9 includes the ability to write private and static methods in interfaces.

    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 launch it by entering jshell into the command line and start writing code immediately.

    JShell command line code in Java SE 9
    The Java JShell command-line tool is excellent for testing small snippets of code.

    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:

    Autocomplete and history of interactive Java JShell
    A new REPL tool called JShell allows you to save and load from files and lines of code.

    Source: Java SE 9

    About the author

    Jozef Wagner

    Java Developer Senior

    I have been programming in Java for more than 10 years, currently I am working in msg life Slovakia as a senior Java programmer and I help customers to implement their requirements into Life Factory insurance software. In my free time I like to relax in the mountains or play a good computer game.

    Let us know about you