For the seasoned Java it's very easy to switch to kotlin. Even more, thanks to the great effort of team for java interop, there is no need to wait for the greenfield project to start to write kotlin code. You can start straight away by either implementing new functionality in kotlin or converting existing classes into the new language by employing Intellj Idea automagic converter
This is a first of this series of posts unioned by tag #kotlin-showoff
As from my experience it takes literally two days for average developer to switch to kotlin from java and start to write meaningful business logic
As time goes by code can use more kotlin specific constructions which make code much more readable and expressive. In this blog post I'd like to show off some of the nice functional constructions which help to make code more idiomatic.
Extracting data from the nullable types
Say, we have an class Address
within UserInfo
which holds information about the given user's address. UserInfo
is a part of the Person
. UserInfo
can be nullalbe as well as Address
but we want to extract city name. In java it would look like:
Person person;
String city;
if (person.userInfo != null && person.userInfo.address != null && person.userInfo.address.city != null)
city = person.userInfo.address.city;
else city = "Unknown city";
System.out.println("User is in " + city);
If you think it's a safe code I have for you. Savvy java developer can immediately spot the issue - between checks and to city
bunch of things can happen on another threads and eventually we can end up with null
Hello NPE!
The correct approach would be to capture values while we're performing the check:
UserInfo userInfo = person.userInfo;
if (userInfo != null) {
Address address = userInfo.address;
if (address != null) {
city = address.city;
}
}
if (city == null)
city = "Unknown city";
System.out.println("User is in " + city);
Expressivity is not Java best strength. But wait, with Java 8 we can make it a bit more readable (and still safe):
city = Optional.ofNullable(person.userInfo)
.map(userInfo -> userInfo.address)
.map(address -> address.city)
.orElse("Unknown city");
System.out.println("User is in " + city);
Looks better, isn't it? Wait for kotlin
println("User is in ${person.userInfo?.address?.city ?: "Unknown city"}")
Sorry java ¯\_(ツ)_/¯
So what exactly happens here? The person.userInfo?.address?.city
either city if it's null
null
Then using operator we make expression to return city
or string "Unknown city". Even more, we can concatenate everything in one string as an expression
You can eat your cake, and have it too
Is it safe one might wonder? Yes, it is. Look into the generated code:
public final class KotlinImplKt {
public static final void kotlinImpl() {
StringBuilder var10000;
String var4;
label14: {
Person person = new Person();
var10000 = (new StringBuilder()).append("User is in ");
UserInfo var10001 = person.userInfo;
if (var10001 != null) {
Address var3 = var10001.address;
if (var3 != null) {
var4 = var3.city;
if (var4 != null) {
break label14;
}
}
}
var4 = "Unknown city";
}
String var1 = var10000.append(var4).toString();
boolean var2 = false;
System.out.println(var1);
}
}
Check out other posts in #kotlin-showoff