Kotlin inline functions

kotlin Mar 6, 2021

This is a post in the "Kotlin, the essence of Java" series. Please read the Kotlin essentials if you're new to Kotlin.

A very simple but effective Kotlin construct is  the 'inline function', a one-liner that actually is one line.

Adding  a function

The Person class from the first post could do with an age() function, in Java this would be:

class Person {
    // ... a lot of redundant Java code and some good bits
    private LocalDate birthDate;

    public int age() {
        if (birthDate != null) {
            return Period.between(birthDate, LocalDate.now()).getYears();
        } else {
            return 0;
        }
    }
}

In Kotlin it's a lot simpler:

class Person(
    var name: String,
    var birthDate: LocalDate,
    val userID: String
) {
    fun age() = Period.between(birthDate, LocalDate.now()).years
}

This is how Kotlin improves on Java:

  • The function is public by convention
  • The return type is inferred from the expression (Int)
  • Because birthDate is not nullable, we don't need to test for it
  • If the function is a one-liner you don't need a body and return, the = does the same
  • Because of the JavaBean convention, Kotlin can access getYears() as .years

Away redundancy, away!

See how I left out most of the Java code in this example to focus on the age() function? The Kotlin example holds the code for the whole class and it's still very readable.

Adding default parameter values

Let's add an optional reference date parameter to see how old a Person is on a certain date. In Java:

public int age(LocalDate refDate) {
    if (birthDate != null && refDate != null) {
        return Period.between(birthDate, refDate).getYears();
    } else {
        return 0;
    }
}

public int age() {
    return age(LocalDate.now());
}

In Kotlin this is easy using a default value for the refDate:

fun age(refDate: LocalDate = LocalDate.now()) 
        = Period.between(birthDate, refDate).years

The improvements over Java:

  • The refDate is not nullable in Kotlin, so no need for (yet another) null-check
  • The default value introduces two forms of the function: with and without parameter. No need to write them separately
  • If you call it without a parameter, the default applies and it will return the age of the person today:
Person susan = Person("Susan", LocalDate.of(2000, Month.JANUARY, 1), "mightysusan")
print(susan.age()) // 21 at the time of writing
print(susan.age(LocalDate.of(2014, Month.MARCH, 3)) // 14

Next steps

Start (re)writing your code with what you learned here. Use the Boy Scout Rule ("Always leave the code better than you found it.") to clean up classes when you change them. Lean back and admire...

Then pick another post from the Kotlin, the essence of Java series to read.

Tags