Sitemap

Kotlin is the better Java

14 min readOct 20, 2024
Press enter or click to view image in full size

Summary

This article provides just another take to the Java vs Kotlin debate. While Java definitely has earned its place in enterprise software development, Kotlin has proven to be a strong and versatile contender as a modern JVM language. Used alongside Java, both can form a powerful combination of robustness, maturity, simplicity and modernity. Does it even has to be a vs and why is Kotlin still so underutilized in backend software development?

Let’s find out.

Motivation

About 5 years ago, I switched from Java to Kotlin as my main backend language. And I never looked back since.

Press enter or click to view image in full size

Some time ago, I entered a position that involves external project work. I was excited and curious to find out what and how other people out there were building with my favorite programming language, joined the job boards — and have been pretty disappointed ever since. Instead of a flourishing market of interesting projects, I found a situation that felt more like wandering through an empty desert. People don’t do server-side Kotlin that much? Migrating Java applications to Kotlin is not a widely adopted practice by now?

Press enter or click to view image in full size

At the time I wrote this article, Stepstone listed 1.181 Java jobs vs 90 Kotlin jobs. And I didn’t even filter out the Android stuff.

I fell so much in love with adapting Kotlin in an otherwise traditional Java environment, that I nowadays only consider Java as legacy leftovers in my projects, patiently waiting for their time to be refactored. Only to wake up to the realization that I might live in a bubble.

So are people generally blind towards the fact that Kotlin can be a great successor to Java in the enterprise world, or have I hopped on board of a hype-train I struggle to hop off?

I wanted to take a moment and look at the recent development of Java as a language, as my memory of actively using it dates back to Java 11.

What happened since I kind of dumped it? My views on Java might be outdated, so let’s fresh them up.

Kotlin is the better Java.

Will I die on that hill? We’ll see.

As an ex Java dev…

Don’t write me off as just another Java hater who never really worked with the language. Back in the days, when I switched from C to Java, I really liked that the latter had a garbage collector. I even got used to it’s weird way of structuring code called “object orientation”, a paradigm I like using to this day. In all honesty, I really liked Java at that time. The language has done me a great service and shaped the way I think and write software. Same as C, but I still wouldn’t want to use it for production code at my workplace (Although I have the upmost respect for people doing that).

Why am I bringing this up? I can be very rewarding to let the language you focus on evolve alongside you. As long as you don’t end at that weird end of the spectrum where you’ll be able to write “hello world” in a bazillion niche languages but never stick to anything enough to get real stuff done.

Nowadays, one might look into Go where they have used C years ago. And I think Kotlin is to Java what Go is to C: a modern take on the classics.

The decision to move on to Kotlin wasn’t even mine at that time. The company I joined was in the midst of migrating a 15 year old, pretty massive codebase from Java to Kotlin. I have never heard of Kotlin back then. 6 years have since passed. Here are some hot takes my brain developed ever since:

  • Javas ecosystem is a great base to use, writing “plain” Java is legacy
  • Kotlin has matured enough to no longer be considered experimental and it’s not going anywhere.
  • The value of Kotlins interoperability with Java is massively underestimated and underutilized
  • I would consider switching back to “plain” Java if it didn’t feel like a huge step backwards.
  • No one who is serious about learning and adopting Kotlin will ever want to go back to “plain” Java.

The latter point is based on the fact that I never heard a single colleague of mine say “Yeah this Kotlin thing is ok, but I wish we’d go back to Java.” And they were all once Java devs. I’d like to emphasize how rare it is for all developers to agree on something. The developers might not even be the problem here. Sure, some Java veterans and genuine fans may oppose the adoption of Kotlin on principle. If only they knew that if they like Java, they will love Kotlin… Anyways, migrating a codebase sounds like burning cash to management people. That is probably a big part of the problem.

If only they knew that a Java -> Kotlin migration is as easy as it gets and can be done as part of day-to-day business. Revitalize dusty legacy projects, get stuff done quicker, all that good stuff is not that hard to achieve. More on that later.

What can Kotlin do for Java devs?

As a general purpose, multi-paradigm language, Kotlin is very flexible and its code can be designed very differently depending on your background. A JavaScript dev might utilize event-driven and functional features while Java devs heavily implement OOP principles. I bet you’ll notice my Java origins while reading my Kotlin code. While I use OOP for the general structure of my code, I also like to sprinkle in some other paradigms where they shine.

Java does this too with e.g. the stream API, but in Kotlin, you have much more flexibility.

One argument I heard was people worrying about not being able to enforce coding standards in such a flexible environment. While Java certainly enforces a standard way of doing things more, Kotlin leaves more room for teams to decide on a favored standard approach. Sticking to those standards lies in the hands of the devs involved, which can be a challenge, but is definitely doable. If that’s what you’re looking for, you could write Java code using Kotlin syntax, which is already a big win as Kotlins syntax is much more clean, concise and elegant. At the very least it gets rid of ALL the annoying boilerplate that really helps people to make fun of Java. And you get that without pulling in an external lib like Lombok. Having to pull in external libraries to be able to somewhat decently work with your language belongs in the JavaScript realm and should definitely stay there. Speaking of libraries, we’ll get to them later. Spoiler alert: they’ll probably not be a valid argument against Kotlin.

Language design: the Builder pattern

Another example of how you can make your life so much easier with Kotlin is the Builder pattern.

Press enter or click to view image in full size

Java constructors become basically unusable when objects have a somewhat large amount of properties. This is where the builder pattern comes in. While being very handy, these builders come with a lot of boilerplate in the background. You can throw Lombok onto the problem, sure. But what if you didn’t have to do any of this in the first place? Let’s have a look at the problem we want to solve:

Most of the time, we are looking for a way to instantiate (huge) objects flexibly, manage nullability and provide default values and practices for object instantiation across the codebase. Kotlin comes with a feature that makes implementing this much easier: named arguments. The order of the properties in the constructor? Doesn’t matter. Need default values? Just define them in the constructor. Mutable class? Still no boilerplate (except equals() and hashCode()).

While you can use Kotlin constructors without named arguments, resulting in the same behavior as Java constructors, named arguments enhance readability and completely eliminate the need for argument management. Just look at the behind the scenes.

Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size
Press enter or click to view image in full size

30 lines vs 182. I intentionally did not cut anything because just look at the carpet. It’s hilarious.

These are mutable classes. For immutable classes designed for e.g. DTOs, both Kotlin and Java offer special options. That comparison is not as funny, but still won by Kotlin imho.

Kotlin has data classes. They contain immutable values (technically you can use mutable variables in data classes, but that kind of goes against the idea behind them), getters+setters are implicit by default, equals() and hashCode() are implicitly generated based on the parameter values and data classes come with some handy utility functions like .copy().

Since Java 16, Java records are production ready. They offer mostly the same features as Kotlin data classes. Their constructors are — like in general — not as strong as Kotlins, so multiple constructors and/or a builder is still required. Apart from that, they are a huge improvement. Kotlin however, made the whole builder pattern obsolete by a clever design choice.

Press enter or click to view image in full size

And this won’t be the last time Kotlin makes common tasks in Java development so much simpler. Less code, same functionality, more

Javas evolution and lingering pains

After giving an example of how Kotlin is better than Java, let’s look at some good stuff that has happened in the Java realm over the last years.

Press enter or click to view image in full size

Check out Fireships video on Java 21. Java has beautified its main method. Say goodbye to good old psvm. But why? Is this hinting towards something bigger? Why just the main method?

As mentioned in the video, this is intended to improve accessibility for newcomers. At least until they want to do something outside of the main method, where they’ll meet some public static int utilityFunction()s who are annoyed that their big brother got a new, fancy T-shirt and they didn’t.

Mocking aside, a good starting point. I hope to see this tendency adopted in a broader manner, but doubt we’ll see anything like a general syntax overhaul anytime soon (or ever) as that would probably mean massive breaking changes.

Another very nice thing I already mentioned are records. They weren’t around back in my Java dev days, so no fresh hot stuff, but still pretty cool.

Press enter or click to view image in full size

A real banger coming with Java 21 is structured concurrency with Java Virtual Threads. One thing where Kotlin beat Java is Kotlins non-blocking structured concurrency support with Coroutines. Java had nothing comparable. Until now.

Press enter or click to view image in full size

There are some nuances between the two, what they focus on and where they shine, see Coroutines and Loom behind the scenes by Roman Elizarov (18:25) for a detailed comparison. Depending on the needs of your application, you will prefer one or the other or maybe even use both together.

Java now also supports String templates. A small detail that makes working with Strings a lot more convenient. While Kotlin offers a single way of usage included in the standard String type, Java offers multiple ways of handling String templates. See more here https://www.baeldung.com/java-21-string-templates. When you have access to String templates in your language, you will probably use them a lot and see them missing in other languages as a sour taste.

This section could go on for a bit…

Here is a list of new stuff that has been added to Java since jdk 8. https://advancedweb.hu/a-categorized-list-of-all-java-and-jvm-features-since-jdk-8-to-21/.

We’ve definitely gotten a lot of improvements over the years, even though some of these improvements were usable in Kotlin years before they were introduced in Java. Java does carry the weight of almost 30 years of presence in the industry. It’s only logical that a legacy language like Java will take more time to adopt modern trends. The most important distinctions between Java and Kotlin can be found here: https://kotlinlang.org/docs/comparison-to-java.html.

You’ll find that Kotlin still has plenty of things Java hasn’t. I find myself using Lambda expressions + inline functions, extension functions, concise nullability with var/val properties, better primary/secondary constructor handling, companion objects, default arguments and named parameters, smart casts, type inference and the when statement a lot in the context of “standard, regular web backend development”. So quite some useful stuff. Some of the other features on the list come handy in specific use-cases and settings only or if you like doing fancy stuff for the sake of it. That applies to both Java and Kotlin (you don’t really need every little niche feature to write good and working code). A major thing I still prefer in Kotlin is null handling.

Press enter or click to view image in full size

No more @NotNull/@Nullable annotations, no more if-parties all over the place, non-nullable fields are actually non-nullable. Nice!

On the other hand, this can also be a disadvantage as the shorthand “?” makes null-handling so cheap that it might be abused especially by newbies. It definitely helps to have experience with null handling in Java before you switch to Kotlin to understand the core concepts of nullability and how it’s supposed to be dealt with. Same goes for getters and setters. You can still hide those details later, when you don’t gain any insight anymore and stuff just becomes repetitive and annoying. That’s also why Java is so popular in education. Java teaches you core concepts — even if they appear dusty and boring — and forces you do deal with them. Kotlins decision to completely get rid of checked exceptions seems to appear like a controversial choice to some. I believe one is perfectly capable of doing proper error handling with unchecked exceptions only. Checked exceptions can become such an inconvenience when software grows in complexity, leading to people using questionable workarounds (like Lomboks @SneakyThrows) aiming towards being able to just ignore them. So yeah, I don’t miss them. You probably won’t either.

The Hannah Montana approach

Glad you’re still around, it’s time for a pitch. What if you combined the rich, mature and powerful Java ecosystem with a convenient, modern and neat programming language? You’d receive a stack with lots of opportunities to shine. With Java/Kotlin, you can revitalize legacy projects and start building software that is

to work with.

You want to implement a new project but are worried that modern languages do not offer an ecosystem that suffices all your business needs? No Problem, Java/Kotlin has your back.

For legacy projects

A codebase migration sounds like a time consuming, expensive and business blocking task. Rightfully so, as migrating a codebase to an entirely different, incompatible platform is indeed a huge project with risks involved. However, a Java-> Kotlin migration is something entirely different. Thanks to Kotlins interoperability with Java, you can just slap it onto your project and get started right away. The migration itself can be performed with whatever speed and structure your team feels comfortable with. There’s also amazing tooling out there, like a Java->Kotlin converter function integrated in everyone’s favourite Java IDE, Intellij Idea. You can migrate most of the code without any or with minimal manual adjustments. Writing new files in Kotlin and converting every Java file one stumbles across during regular development with some refactoring fridays sprinkled in to move the migration forward more intensely worked very well in one of my former projects. That codebase was pretty old and pretty massive, so this doesn’t only work for small projects. The project felt a lot fresher once Kotlin started to spread. One of the best decisions we ever made. There are limitations regarding how old the Java version in use can be. Since Kotlin version 1.5, only Java versions >= 8 are supported. You won’t be able to migrate Java 1 code to Kotlin. If your project runs on >= Java 8, you’re technically ready to take it to the next level.

For new projects

Kotlin is a great platform for modern application development. With Kotlin multiplatform, you can build truly platform-independent, reusable applications, which is not only useful for mobile applications. Used with e.g. Spring Boot, it can be used to build powerful web servers. Again thanks to interoperability, you can use countless libraries from the Java ecosystem to boost functionality and efficiency. The argument of having limited resources when compared to Java only applies to language related topics. These are also not really that noticeable. The Kotlin community is very alive and active, and I have never found myself being stuck because I didn’t find proper resources. Before you decide on Java for a greenfield project, seriously consider going with Kotlin. Although migrating after some (or a lot of) time will always be a considerable option, so you’re not locked in to that decision. It’s never too late, you can switch any time.

Kotlin learning curve for Java devs

One argument I sometimes stumble across is that people do not want to have to train their teams on a new language. My experience is that Kotlin comes very naturally to people of Java origin. At my previous job, we regularly hired Java developers to work on our former Java, now Kotlin project. Experienced Kotlin developers are still a pretty rare resource on the market due to the hen or egg problem in the pipeline. I’ve never seen any of the newly hired Java devs struggle with getting into Kotlin. They were productive in a short amount of time.

In the first stage, you get used to the different syntax, the null handling and the absence of checked exceptions. Then you dive deeper into Kotlins distinct features and adopt them where you see fit. You can adopt many patterns and idioms you know from Java and that background makes the learning curve very manageable. It definitely helps/speeds up things if at least one experienced Kotlin dev is present on the team for guidance. However, I would say that’s not a requirement. It can also be a fun experience as a team learning and getting into it together.

Kotlin as a hiring benefit

You may have noticed a considerable amount of developers who have tried Kotlin and fell in love with it. Many of them being former or active Java devs. Like me, they turn up their noses at the idea of having to work on a Java project again. Once you’ve got a taste, it can get a strong priority on the job search. If you’re a small to medium player in the industry and struggle to find good and motivated people, this might be an action to boost your attractiveness. While your job postings can get lost in the vast sea of Java postings, they are much more present when searching for Kotlin. I would argue that you can attract greater talent by signaling an openness to modern technologies and improvement than by offering just another standard Java legacy job.

Press enter or click to view image in full size

Conclusion

While Java has come a long way and I respect what it has done and continues to do for enterprise and the development community, I am still firmly sitting on my seat on the hype train. I hope I have been able to give some doubters some food for thought with this one. My bubble is a great place to live in, and I gladly invite everyone to join!

--

--

Plexify GmbH
Plexify GmbH

Written by Plexify GmbH

We offer sophisticated Software Development Services and personell with Java, JavaScript, Golang and Python on the Google Cloud Platform. www.plexify.io

No responses yet