We would face a similar problem if we were talking about the number of different devices running Android today; if it weren't for Java. Java's power, and the fact that it is used on billions of devices today, comes from its ability to run on any device regardless of its hardware and software, provided it has an interpreter for the pseudocompiled code generated by the Java compiler.
Is Java the solution to all our problems?
Unfortunately, nothing could be further from the truth. Although Java solves the problem of interoperability between devices, it opens up a new set of headaches that we'd like to remove from the equation. Some of them are:
No built-in support for optional parameters
Although it does have support for immutable collections. Despite the existence of the Optional class, using it means generating a lot of boilerplate code that we could avoid if support for options were built into the language itself rather than added as an extension.
No native support for functional programming: Java has the Stream API (I'll repeat that it's only supported on Android starting with API 24), but its integration into the language feels like an afterthought: it fits awkwardly with objects associated with primitive types (IntStream, DoubleStream...) and uses the Stream class for all other objects.
Support for anonymous functions (Lambdas). Although Java 8 implements support for Lambda functions, they are not first-class; this means that, while we can use lambda expressions to implement anonymous interfaces with a single method, Java does not support passing functions as method arguments.
Furthermore, the lack of type inference makes writing Lambdas rather awkward, especially when trying to simulate functions such as function composition or currying; the language doesn't support them.
Nullable types: although this could be included in the section on optional parameters, the scale of this problem deserves a special mention. How many Java programmers have filled their code with if (foo! = Null) to try to fight the dreaded NullPointerException? (In fact, its creator apologized for what he calls the “billion-dollar mistake”.) And how many of these checks are anything more than workarounds to keep our app from crashing?
Manual view binding: although this problem is specific to Android as a platform, rather than Java as a language, it's also worth pointing out how much boilerplate code is needed to get a reference to an Android view. Although we managed to get rid of the hated findViewById (int id) thanks to data binding, we still need to keep a reference to that binding.
More generally, but no less importantly, Java is a very verbose language; it requires writing a lot of code for any operation, as well as generating a lot of files (one per class). The first problem can make code more expensive to maintain and more prone to errors. The second leads to class proliferation.
Many of these problems, although solved in Java 8 and 9, are unavailable in the Android SDK below API 24, which makes them virtually unusable.
Why does Kotlin solve all these problems?
It's for all these reasons that Java is now considered a language that, at least for Android development, isn't evolving at the same pace as the industry.
Over time, the need for a language with real, native support for everything mentioned above has become increasingly urgent, while also preserving Android's key feature, outlined at the beginning of this article: its ability to write and compile a single app and make it run on any device and version.
Many possibilities have been explored in this direction, some involving the use of Swift or Scala, although none of them has been very promising.
All this changed with the arrival of Kotlin.
To demonstrate this, we can list all the downsides we encounter in Java and how Kotlin handles them:
Options.
They're built into Kotlin; all you have to do is declare a variable type ending in a question mark? and it becomes an optional type. Kotlin also provides a way to safely unwrap these options, listener?.onSuccess(), without checking whether the option has a value, and it provides the Elvis operator as well.
Functional programming: in Kotlin, we find built-in support for working with collections and datasets, such as Streams. We can call .flatMap {} directly on a collection, as well as .filter {}, .map {} and many others. Type inference makes using lambda expressions especially convenient.
Lambdas and higher-order functions. The previous point leads to the fact that in Kotlin, functions are first-class citizens. We can define functions that take other functions as parameters. An example of this is the definition of the map function itself:
Although this code might look a little chaotic at first glance, the part we're interested in is the following.
This means that the map function has a parameter named transform, which is itself a function with an input parameter of type T that returns an object of type R.
Thanks to this built-in support for lambda expressions in Kotlin, we can use the map function like this:
This code snippet will return a collection of elements of the type returned by aTransformation.
Nullable types: since Kotlin has built-in support for optional parameters, our code should have as few nullable values as possible. But even so, if they do occur, Kotlin offers us tools to deal with them more easily than in Java. For example, we have the safe-call operator (?) to avoid a NullPointerException when accessing optional parameters, or the safe-cast operator to protect us when we want to perform a cast.
What's more, the Kotlin compiler forces us to keep track of nullable types and even introduces runtime checks for compatibility with Java code.
View binding: this is an Android-specific problem, so JetBrains offers us Kotlin Android Extensions, the official support library for making this problem (and some others) easier to deal with, using a Gradle plugin.
All of the above, along with a large number of other features that didn't make it into this article or weren't really important to us, shows that Kotlin seems to be the most promising bet for the next few years in the world of mobile development.









