
Java programmer expert
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.
V článku sa dozvieš:
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 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) 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.
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) 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.
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.
So, if you are considering which version to choose:
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.
Most common problems during migration:
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 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.
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.
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.
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.
…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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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:
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
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.
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.
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.
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.
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.
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.
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.
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.
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.
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).
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.
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.
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.
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.
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.
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, 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 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.
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.
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.
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.
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 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.
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.
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.
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.
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.
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).
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.
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.
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, 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.
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 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.
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.
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 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.
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.
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.
This allows developers to use patterns in switch conditions. It provides greater flexibility and expressiveness compared to using constants.
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.
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
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 was released in September 2020 and brought with it three major updates:
Text blocks, which were introduced as a preview in Java 13, became a language standard.
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.
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
In March 2020, version Java SE 14 was released and brought as many as four significant improvements:
The switch expression, which was introduced as a preview in Java 12 and enhanced in version 13, became a language standard.
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.
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:
In this case, the new keyword record was also used, which automatically adds constructor methods, getters, equals, hashCode, and toString.
Version 14 introduced pattern matching to simplify code. Without the new feature, the code would look like this:
Thanks to the new version of Java, however, the code looks much simpler and shorter:
Source: Java SE 14
Java 13 was released in September 2019. The update came with two major improvements:
The new text blocks feature allowed developers to more easily read multi-line texts. It uses three quotation marks, similar to Python and Groovy.
In addition, all features of the String class are available.
Java 13 improves the switch expression from version 12 with the yield keyword. With yield, values can be returned from a switch expression.
Source: Java SE 13
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.
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
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:
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:
The key change in this version is that the programmer does not need to explicitly compile Java source files with the javac command.
Instead, the file can be run directly using the java command.
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.
Source: Java SE 11
Java SE 10 was released by Oracle in March 2018. It brought two important changes for developers:
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 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 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:
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:
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.
Another feature of Java 9 enables writing private and static methods in interfaces in order to avoid redundant code.
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.
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
Related articles