The human’s natural instinct in most cases is to always want the best and the latest. Does that mean everyone should upgrade to the latest version of Java whenever there is a new release? For example, should you migrate to Java 17 now? The Latest does not always mean the best – but is that the case here? Let’s dive in!
But wait – there’s Java 18! Why are we even talking about the latest and greatest if, in fact, there is a newer version? Even though Java 18 is also available, we would rather not review it as it does not offer long-term support (LTS) and its support span is of 6 months only, which does not make it production usable. Most businesses usually stick with a version that provides long support unless the project strictly requires a migration to a newer version. If you need to migrate or you’re just curious about the features & downsides, stick with me for a bit more.
Disclaimer: We will review only the LTS versions, which are 8, 11 and 17 as they’re the ones that are widely used across different projects. And in case you’re still not sure what technology to use for your next project, here are five reasons to choose Java.
Migrating from Java 8 to Java 11
There are several changes worth mentioning here. Some of them might be not as important as others depending on what you currently use. But let’s talk about prerequisites first. You would simply need to:
- Change your Java version to 11 from 1.8 (not to be confused with 1.11).
- Make sure all dependencies that you are using are compatible with the new Java version. For example, Spring Boot 2.0.x and earlier do not support Java 11.
Changing and updating packages could be a tough job. Luckily, many people have provided proper documentation regarding “what updates to what” thus it should be pretty straightforward. To save you some time, StringUtils and Mockito are some of the most common packages that have to do with this upgrade. However, you must have heard of them or use them already in your project. We will also add some other worth mentioning features.
- StringUtils base package changes from org.apache.commons.lang to org.apache.commons.lang3. This offers a great variety of operations with objects, as a whole.
- Mockito gets upgraded once the Spring gets upgraded and there are several small changes:
– MockitoAnnotations.initMocks(this) becomes MockitoAnnotations.openMocks(this) ,
– MockitoJUnitRunner is no longer in org.mockito.runners but in org.mockito.junit,
– Instead of Matchers , we would need to use ArgumentMatchers (basically the same but with more features). - Var keyword – developer-friendly keyword and used to introduce new variables without specifying the type, as the Java compiler infers the type of the variable at compile time.
- Modularity – introduced in Java 9, we can now split our program into different modules, providing easily testable code and proper management in which you can specify and see which code is public or not.
- JavaFX is removed from OracleJDK in Java 11
- Changes in the garbage collector – the default in JDK 8 is Parallel whereas in JDK 11 it’s G1 , which is slightly better, although there are several use-cases where it loses the battle.
- New String methods – we are introduced to a couple of new very helpful methods such as isBlank(), strip(), lines(), repeat(N) and others.
- New methods to work with files – isSameFile(), readString(), writeString() are being introduced.
There aren’t really that many differences between working with different versions of a dependency with some exceptions. For example, in previous versions of Mockito if you used any(T.class) providing a null, it would work just fine. However, with 2.x version, you would need to use ArgumentMatchers.nullable(T.class) as any(T.class) includes only T.class references and not null. Dive deep into the dependencies you are using and their changes. This is to make sure you’re aware of such cases where you need implementation updates of tests or features.
Migrating from Java 11 to Java 17
Java 17 was released in September 2021 and it will take some time to take over the throne from Java 11. Nevertheless, the features it offers save a lot of coding and needless boilerplate logic. Here are some of those features, so that you can decide whether to migrate to Java 17:
- Switch expression – can now return a value
- Prior to Java 11, switch cases would look like this:
- Whereas now, you can do this:
- All blocks are multiline blocks and yield is the keyword to return the value.
- We can also add lambda expressions
- Text Blocks updates – It is no longer required to escape certain symbols and it is far more readable, here’s an example:
- Before:
- After:
- Records – If you are familiar with Lombok annotations – that’s exactly what this is – container classes with getters/, constructors and also equals/hashcode and toString methods. All you need to do is to use the keyword record and specify the class and the parameters you would need – that’s how easy it is to create a DTO.
- Enhanced instanceof
- Before Java 17, we first had to check the type. Then, we had to cast the given object to the specific type – like this:
- Now, all we need to do is just check the type – no more casting:
- The even better garbage collector – Here you can see the difference between the Java versions and garbage collectors – the blog shows the changes in different areas like latency, throughput and footprint.
Should you jump on the Java 17 hype-train?
As painful as some migrations sometimes are, it might be a good idea to migrate to Java 17. Of course, this is depending on the number of dependencies you have. We’ve talked that Java17 offers better performance and better optimization in terms of code. Imagine being able to deliver the same feature with a lower amount of coding. Plus, the code would be more readable for other developers. This is a huge benefit as some dependencies stop supporting certain Java versions.
In conclusion, if you are on Java 8 – I would strongly recommend you migrate to Java 11. If, however, you are on Java 11, I would suggest reviewing the changes in-depth. If the upgrade is seamless and you would benefit from the newly introduced features, then feel free to go for it. Remember that as software engineers, time is our most valuable asset. If it would take too much time and provide no benefits, then migration won’t be necessary. At least, not for now.
In the project that I started, we were using Java 8 at first but migrated a few months later to 11. Although we might skip the migration as of now to Java 17, we keep on talking from time to time about it and how easy it will be to create different DTOs using records or use the enhanced instanceof operator. It is truly amazing how many new optimizations are there to make the code more developer-friendly.
I’m eager to learn which direction will the evolution of Java take in the future and if so are you, feel free to message me and I would be happy to discuss this topic with you.