Kotlin vs. Java—Developing Native Android Applications
Engineers are known for a strong desire to experiment with new tools that would increase productivity, prove handier, or are just fancy.
For years Java was the only language that could be applied to creating native Android applications. Back End developers could play with new languages and paradigms. On Android, however, we had been stuck with Java. The community has been experimenting, and in time, we could observe Android applications written in Groovy or Scala. In both cases, it worked, and developers were able to use language that is not officially supported, but also solutions that have never become a popular way of creating Android apps. Although Scala or Groovy could be considered more productive than Java, both of these languages make developing uncomfortable as they are placed in the build toolchain of the Android environment.
In 2011, JetBrains unveiled Project Kotlin. From the very beginning, it was ready to use as the main language of an Android app. Finally, Google announced that from 2017, Kotlin is a first-class citizen in the Android environment and gained official support.
The choice between Java and Kotlin for your next Android application requires considering all the pros and cons of each solution in the context of your project.
Kotlin was announced as production-ready in February 2016. It is easily integrated with Android build toolchain and comes with working and well-documented interoperability with Java code. Thus, developers could start using Kotlin even in the middle of the Back End or mobile projects. As an open-source, statically typed language working in the JVM ecosystem, it was designed to address various Java issues and to improve developer’s productivity.
Thanks to the enormous quantity of tutorials, excellent documentation, and a friendly ecosystem, it’s easy to begin working on Kotlin. Jetbrains provided a tool integrated into Android Studio that can convert existing Java classes to Kotlin. The language provides a lot of sophisticated constructions that could improve the productiveness of the whole team—the less code is written, the less must be read by other developers.
Even an inexperienced Kotlin developer will take advantage of it because of the reduction of the boilerplate and null-safety mechanism that is built into the language. It is worth mentioning that an app written in Kotlin still can use any library written in pure Java.
Switching to new technology is always risky. Kotlin improves team productivity, but when all the team members have never used Kotlin, velocity will likely decrease until developers get familiar with the new concept. Additionally, learning a new language under pressure of tight deadlines may lead to a situation where the code is written in Kotlin, but barely any of the fantastic possibilities are used, and the code architecture looks like Java but with a slightly different syntax.
Java, created by James Gosling in 1996, has been continually evolving and adapting to new paradigms, possibilities, and trends. At the moment of writing the article, the latest released Java version is Java13, but Androids support only truncated Java8.
Java is an extremely widely used and mature technology. There are a lot of experienced Java developers on the market, so it should be easy to form a team that could effectively work on a project. Starting an app in Java might be a good choice for inexperienced engineers because Java is used in the documentation and many Google sample apps.
Considering Java8, it requires a lot of boilerplate—the issue is addressed by some libraries, but using them just moves the issue to another dimension instead of purging it. Java is a verbose language. While it could be an advantage for Juniors, it is painful for experienced team members because instead of one, descriptive line in Kotlin, we get even a dozen lines in Java.
There are a lot of differences between these two languages. Kotlin does not provide some features known from Java, e.g., non-private fields, ternary operators, wildcard-types, or checked exceptions. On the other hand, Kotlin comes with extensions functions, null-safety, Data classes, smart casts, coroutines, and a lot more.
I would like to consider two aspects that have a significant impact on the source code, setting aside the experience level of your team.
The famous Billion Dollar Mistake. In Java,
null is the first-class citizen and could be assigned to the variable on any type (instead of the primitive one). In Kotlin, the type system distinguishes between references that can hold
null and those that can not. If only a developer tries to assign
null to non-nullable reference, it renders a compilation error. It works analogously for nullable reference. Each access to nullable reference that is not preceded by a null check leads to a compilation error. Moreover, Kotlin can identify if the reference is available in a single thread or could be reached from various threads.
There is no checked exception in Kotlin. However, there are some advantages of checked exceptions. Jetbrains decided that problems, to which checked exceptions lead, are not balanced by benefits.
“Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result – decreased productivity and little or no increase in code quality.” — Bruce Eckel
Java forced catching or rethrowing exceptions. It is said that often, there is no need to handle exceptions, and it leads to empty
Java and Android do not provide any secure, handy, productive threading mechanism. This is why, e.g., RxJava—apart from any other advantages of the library—is widely used to perform asynchronous operations.
Kotlin brings Coroutines, a concurrency design pattern based on light-way threads. Thanks to coroutines, a developer can write code that looks like a list of sequential actions and is perfectly readable.
Like any other technology, Kotlin has some problems and is based on some decisions that could be wrong for the part of the community. Some of the features could be extremely surprising for an experienced Java developer. Some mechanism works perfectly fine until they are used with a library written in pure Java. Kotlin allows for argument name shadowing, which leads to a compile-time error in Java. The null-safety mechanism does not work perfectly fine with Java because types returned from Java code are treated as non-nullable, which is not true in most cases.
Java seems to be a good choice if you have tight deadlines and experienced Java developers. In any other case, Kotlin would be the most reasonable choice. It provides many opportunities to increase developer’s productivity and happiness. Hardly any mobile developer wants to go back to Java if only he or she realizes how to use Kotlin features for a project’s sake.
Jetbrains did its homework and provided language that resolves particular, well-known issues of its opponent along with excellent documentation and perfect toolchain. But it is not the end. Kotlin keeps gaining more features and possibilities. Kotlin JS provides the ability to write JS application that is transpired form Kotlin, and Kotlin/Native brings your Kotlin code to iOS and embedded devices.
Our engineers—skilled in both Java and Kotlin—will be excited to help you with your next project!
Lead Software Engineer