The 11th version of Java, which is LTS (Long Term Support) without exaggeration, was a version that every Java developer noticed. Even though this version wasn't as breakthrough as Java 8, it contributed to the development of Java and also set the direction for the development of this programming language. Changing the set of packages and working with them was the main change in this release. So let's see if it's worth switching to Java 11 if your project is still using version 8 and, if so, what nuances you should consider when switching.
Java resisted dynamic typification for a very long time since it was not part of the concept of easy code readability, but this feature was still added in Java 10 and accordingly became part of the Java 11 release. Abusing var instead of explicitly specifying the returned class always led to the result when it was not clear which classes a particular method operates on; thus, the readability and, in turn, the maintainability of such code were low. Realizing this in Java 11, using var only inside methods was an elegant solution to balance readability and verbosity.
Java 8. Instantiation of an Object:
CustomerOrderRepository customerOrderRepository= new CustomerOrderRepository();
Java 11. Instantiation of an Object using var:
var customerOrderRepository= new CustomerOrderRepository();
Сollection Factory Methods, which were added in version 9, are available in Java 11, allowing you to create collections more concisely and faster. Although the number of elements that can be added at one time is limited, this approach significantly reduces the amount of code when initializing the collection.
Java 8. Creating a List:
List<Integer> integerList = new ArrayList<>();
integerList.add(1);
integerList.add(2);
integerList.add(3);
integerList.add(4);
integerList.add(5);
Java 11. Creating a List using the factory Method:
var integerList = List.of(1, 2, 3, 4, 5);
Even though we get collections with the same values, these two collections have two different behaviors. Using a factory method, you are getting a collection that cannot be modified, and also, such a collection does not support null elements. However, such a collection is more consumes less memory and works more efficiently.
Another interesting innovation that was added since Java 9 is JShell. JShell is a convenient instrument that allows executing Java code in the console. Using JShel, you can run Java code without writing a complete program. JShell allows you to write Java code and see the result immediately, so you can quickly try out different ideas, test code snippets, and explore the possibilities of Java. Here is a simple example of how JShel works.
Java 11. JShell:
>jshell
| Welcome to JShell -- Version 17.0.2
| For an introduction type: /help intro
jshell> System.out.println("Hello JSHell!")
Hello JSHell!
jshell> /exit
| Goodbye
The biggest change in Java 9, and therefore Java 11, is modules. Finally, full support for modules has been added to Java, with the ability to control which packages from the module will be available to others. The flexibility of settings also allows you to specify exactly which modules packages will be available. This update is by far the most noticeable change that has been made in Java 9. JPMS makes it possible to manage packages and select what exact packages from them can be used in other modules. Using this, you can exclude unnecessary packages, to reduces the number of plugged-in classes, and make your program smaller and faster. All major Java packages have also been added to the modules, so you can always include only those packages that you need.
Java 11. Modules:
module com.hkrn.art{
requires java.base;
requires java.sql;
requires transitive com.hkrn.dependmodule;
exports com.hkrn.mainmodule;
exports com.hkrn.secondarymodule;
exports com.hkrn.mainmodule to com.hkrn.anothermodule;
}
In the example above, a module descriptor is shown that illustrates how packages can be regulated in terms of accessibility to other modules. Such a config must be put into the module-info.java file in the root folder of a module. Definitely, this is not everything that modules can do; however, it is worthy of a separate article to describe all the features.
The stumbling block to the migration to Java 11 can clearly be considered the decision to remove packages from it. Although various packages have been removed, the most notable is perhaps the javax.* packages that were used for many enterprise programs. A popular framework like Spring also uses these packages. Although the issue of the missing functionality from these packages can be solved by adding dependencies to maven / gradle or adding jar-files, sometimes it is difficult to find the missing dependency since you need to take into account not only obvious dependencies in the project but also transitive dependencies that come from third-party libraries.
It would not be superfluous to say that in version Java 11, you will also get an improved ZGC garbage collector that will be able to process garbage asynchronously, which leads to minimal delays in the work of the garbage collector and also Flight Recorder, which will allow you to conveniently profile your application.
Undoubtedly, Java with version 11 made another powerful step forward, adding useful tools to Java for more convenient and flexible work with code. However, you need to be careful when migrating to Java 11. The removed packages can gift you a headache when you try to build your project with all the required dependencies. An attempt to add modules to a finished project will make you work hard to set everything up correctly, especially if you are it comes to old projects that are using libraries that are no longer supported. However, despite the difficulties, if the migration is successful, you will get a great reward in the form of a more convenient API, a faster garbage collector, and a profiler that will clearly be useful for evaluating the performance of your application.