Kotlin Features I miss most in Java

s1m0nw1
1,841 views

Open Source Your Knowledge, Become a Contributor

Technology knowledge has to be shared and made accessible for free. Join the movement.

Create Content

Kotlin Features I miss most in Java

Disclaimer: My articles are published under "Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0)".

© Copyright: Simon Wirtz, 2017 https://blog.simon-wirtz.de/kotlin-features-miss-java/

Feel free to share.

My Life as a Java Dev

Although I'm a big supporter of the Kotlin programming language, I still do a lot of Java programming on a daily basis for my employer. Since I'm aware of the great functionalities of Kotlin, I'm often struggling with Java as it has some "pitfalls", requires additional boilerplate and misses many features. In this post, I'd like to describe which Kotlin features I miss most when coding in Java.

new and Semicolon

Ever since I'm doing Kotlin, there are two things I always forget when coding in Java: the new keyword for constructor invocations and the annoying ; to complete statements. Kotlin doesn't have new and even semicolons are optional. I really appreciate this decision because it reduces the "syntactic noise".

Data classes

In Kotlin, data classes are used for simple data containers, representing JSON objects or returning compound objects from functions amongst other use cases. Of course, Java doesn't support this special type of classes yet. As a result, I often have to implement my own data class, which means a lot of boilerplate in Java. One special use case is compound objects returned from functions. For example, let's imagine a function that needs to return two objects. In Kotlin we could use a data class, or simpler, a Pair directly. In Java, I tend to create a value object, which is a class with several final fields, each of which instantiated through the constructor. Similar to Kotlin, I don't implement getters and setters, but use the class's fields directly as public properties. Unfortunately, this is not what we learned as best practice and most Java code style checkers will complain about it. I do not see any encapsulation issues here and it's the least verbose approach in Java. The following shows such a compound object, the inner class Multi. In Kotlin this would be a one-liner.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Main {
public static void main(String[] args) {
new Main().useMulti();
}
public void useMulti() {
Multi multi = helper();
System.out.println("Multi with " + multi.count + " and " + multi.name);
}
private Multi helper() {
return new Multi(2, "test");
}
private static class Multi {
private final int count;
private final String name;
public Multi(int count, String name) {
this.count = count;
this.name = name;
}
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Local Functions

In many situations, we tend to create private methods that are only used inside another single method in order to make this one more readable. In Kotlin, we can use local functions, i.e. functions inside functions (inside functions...), which enables some kind of scope. For me, this is a much cleaner approach, because the function is only accessible inside the function that actually uses the local one. Let's look at an example.

fun deployVerticles() {

    fun deploy(verticleClassName: String) {
        vertx.deployVerticle(verticleClassName, opt, { deploy ->
            LOG.info("$verticleClassName has been deployed? ${deploy.succeeded()}")
        })
    }

    deploy("ServiceVerticle")
    deploy("WebVerticle")
}

It's taken from a sample vert.x application and defines a local function that is reused twice afterward. A great way to simplify your code.

Single Expression Functions

In Kotlin we can create single expression functions, i.e. functions without an actual body. Whenever a function contains only a single expression, it can be placed after a = sign following the function declaration:

fun trueOrFalse() = Random().nextBoolean()

In Java, on the other hand, we always have to use a function body enclosed in {}, which ranges over at least three lines. This is also "syntactic noise" I don't want to see anymore. To be fair, Java 1.8 makes it possible to define lambdas which can also solve this, less readable though:

public class SingleExpFun {

    BooleanSupplier trueOrFalse = new Random()::nextBoolean;

    private boolean getNext(){
        return trueOrFalse.getAsBoolean();
    }
}

Default Parameters

One very annoying part of Java is the way methods have to be overloaded. Let's see an example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Main {
public static void main(String[] args) {
Main o = new Main();
o.testWithoutPrint(2);
o.test(2);
}
public void test(int a, boolean printToConsole) {
if (printToConsole) System.out.println("int a: " + a);
}
public void testWithoutPrint(int a) {
test(a, false);
}
public void test(int a) {
test(a, true);
}
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

We can see a class with a method test(int, boolean) that is overloaded for the default case and also a convenience method is available. For more complex examples, it can lead to a lot of redundant code, which is simpler in Kotlin by using default parameters.

1
2
3
4
5
6
7
8
9
10
fun test(a: Int, printToConsole: Boolean = true) {
if (printToConsole) println("int a: " + a)
}
fun testWithoutPrint(a: Int) = test(a, false)
fun main(args: Array<String>) {
testWithoutPrint(2)
test(2)
}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Calling multiple methods on an object instance (with)

Obviously, Kotlin is more functional than Java. It makes use of higher-order functions in incredibly many situations and provides many standard library functions that can be used as such. One of my favorites is with, which I miss a lot whenever I can't use Kotlin. The with function can be used to create scopes that actually increase the readability of code. It's always useful when you sequentially call multiple functions on a single object.

class Turtle {
    fun penDown()
    fun penUp()
    fun turn(degrees: Double)
    fun forward(pixels: Double)
}

with(Turtle()) {
    penDown()
    for(i in 1..4) {
        forward(100.0)
        turn(90.0)
    }
    penUp()
}

The great thing is the usage of lambdas with receiver, which you can read about in one of my other posts.

Null-Safety

Whenever I work with nullable types since the time I started with Kotlin, I actually miss the type system's tools to prevent null-related errors. Kotlin did a very good job by distinguishing nullable types from not-nullable ones. If you strictly make use of these tools, there is no chance you'll ever see a NullpointerException at runtime.

Lambdas and Collection Processing

Kotlin places a lot of value on its lambdas. As shown in the with example earlier, there's special syntax available for lambdas that makes its usage even more powerful. I want to underline that the way functions and especially lambdas are treated in the language makes it dramatically superior to Java. Let's see a simple example of Java's Streams, which were introduced along with lambdas in Java 1.8:

List<String> list = people.stream().map(Person::getName).collect(Collectors.toList());

It's a rather simple example of a Stream that is used to get a list of names from a list of persons. Compared to what we did before 1.8, this is awesome. Still, it's too noisy compared to a real functional approach as pursued by Kotlin:

val list = people.map { it.name } 

Or yet another example, in which salaries of employees are summed up to a total amount:

int total = employees.stream()
                      .collect(Collectors.summingInt(Employee::getSalary)));

So much simpler in Kotlin:

val total = employees.sumBy { it.salary }

The Kotlin examples show how simple it can be. Java isn't a functional language and has a hard time trying to adopt functional features like lambdas and streams as we can easily observe in the snippets. It really sucks to go back to Java, if you ever experienced the beauty of Kotlin. Have you ever tried to use Eclipse after being familiar with IntelliJ? You know what I mean then.

Wrap-up

In this short post, I presented you my top Kotlin features I always miss when coding in Java. It's just a selection of things, which will hopefully find their way into the Java language soon. But to be honest, there's no reason to always wait for Java, when there already is a much sweeter language available... I want to point out, that starting with Kotlin really made me a much better programmer because I began wondering about certain features in both languages and also try to find ways to use Kotlin-dedicated things in Java by finding workarounds like arranging my code differently.

I'd be interested in the features you like most, feel free to comment :) Also, if you like, have a look at my Twitter account and follow if you’re interested in more Kotlin stuff :) Thanks a lot.

Open Source Your Knowledge: become a Contributor and help others learn. Create New Content