What is Java?
Some of the key features of Java:
- Released in 1995
- Verbose language, lots of boilerplate code
- Large community
- Easy to learn
Java is the preferred language for a beginner in web development over Kotlin, its large community with tons of easy guides from the very start makes it the ideal place to begin. Decades worth of questions and answers on Stackoverflow means you will find answers to practically every issue you encounter.
What is Kotlin?
Some of the key features of Kotlin:
- Released in 2011
- Concise language, can skip most boilerplate code
- Smaller community than Java
- Harder to learn than Java
- Was designed to replace Java by dealing with its technical debt
- Full interoperability with Java
- Runs on JVM, same as Java
- Recommended by Google for Android development (replacing Java) in 2019
As inferred in the list above, one of the main reasons for Kotlin over Java is that it was designed to deal with Java’s huge technical debt. It fixes the billion dollar mistake among others, which is one of the main reason for Google changing its recommended language for Android development to Kotlin. It also has full interoperability with Java, meaning you can call Java from Kotlin files and vice versa, and you can also automatically convert a Java file to Kotlin with a script that IntelliJ has included in its licensed version.
While this means you could technically migrate a project from Java to Kotlin piece by piece, It is not something I recommend doing unless you are absolutely certain you will finish it. Having a project using multiple languages interchangeably will only obscure and confuse, especially if there are developers who are only used to one of the languages. If you plan on using Kotlin, it is better to start on a fresh project.
Differences from Java to Kotlin
This section goes a bit deeper into how Kotlin does things a bit differently than Java (8). It is meant to reduce the amount of confusion you might experience if you try out Kotlin, and as such this is just my selection of things I think is nice to talk about, it is by no means an exhaustive list.
In Java arrays are covariant, meaning an array of Integer is also an array of Number. This is not the case in Kotlin.
Kotlin doesn’t have raw types, instead you have to use star projection.
Java has support for checked exceptions, and if you’ve ever taken a Java certification, you know it’s a big deal. In Kotlin, however, every exception is by design unchecked.
Null pointer exceptions, the billion dollar mistake, Kotlin handles this very differently from Java and is the main reason I think it’s worth to give Kotlin a try. All code in the following sections is Kotlin code.
A type cannot be assigned a null value by default, you have to specifically declare this variable as an optional with the ? symbol.
If a type is nullable, Kotlin now forces you to handle it, while Java would encounter a runtime exception.
There’s various ways to handle this, e.g. a null check or using the safe call operator ?
Safe call operator followed by Elvis operator ?:
If you know a value is never null, you could short-circuit the null safety with the not-null assertion operator !!. This is a poor practice though, and can lead to the exact issues with null safety we want to avoid.
Kotlin also has various helper functions, so if you need to filter a list of nullables, you can do so easily
When handling unknown types, e.g. of type Any, Kotlin will smart cast the type whenever possible. For example type checking if the unknown is a String.
The compiler is also smart enough to see that if type checking in an if block with a return does not trigger, then further down we have that knowledge about the type. The same thing works if you are checking for nullability.
Smart casting in a switch (pattern matching introduced in Java 16 will work to a similar effect)
Type inference and string templates
When defining a type, Kotlin will automatically try to infer the type, even more complex custom types whenever possible. String templates allows us to easily mix strings and functions without the need to concatenate them.
As of the time of writing (Dec, 2022), string templates might come to Java in the future, but the task currently doesn’t seem like it’s being actively worked on.
A data class in Kotlin automatically creates getters, setters and constructor. This is similar to Lombok’s @Data annotation, or Java’s own Record type that was introduced in Java 16.
Assuming we have the data class from the above example, if we want to create a new User, we call it without “new” keyword we use in Java
When data classes get big and it is difficult to see the order in the constructor, the named parameters are a huge help. Not only will named parameters allow you to make the parameters in any order, it also clearly shows which is which, and this is the preferred way to do things. You lose a tiny bit of conciseness by using named parameters but gain a huge amount of readability.
All in all, Kotlin is not that different from Java, and with a short amount of adjustment period a Java developer can get quite comfortable with Kotlin. So if you are a Java developer without Kotlin experience, I encourage you to not turn down projects using Kotlin, but rather go for it instead. After all, Kotlin was designed to be a replacement for Java, and while it is clear it is not completely replacing it (yet?), the fact that it is now the recommend language for Android development should say something.