Kotlin for Java Developers - Part 2


Continuing article on Kotlin for Java Developers, Let’s continue the differences:

Access Modifiers

Default top level visibility is public whereas its package private in java

There is no restriction to have class names and filenames so its possible to declare multiple public classes in single Kotlin file

There is something called private class in Kotlin which means only classes within that file can use it.

fun main () {
    val emp = PEmployee()
    println(emp)
}

private class PEmployee {
    
}

Kotlin has fourth access modifier called internal, which means internal to the module

Kotlin classes can’t see private properties defined in inner classes

It is interested to note that since Kotlin runs on JVM, the code must be compiled to access modifiers which JVM can understand. private is compiled to package private internal is compiled to public

Defining Classes and Constructors

public class JavaEmployee {

    private final String firstname;

    public JavaEmployee(String firstname) {
        this.firstname = firstname;
    }
}
class PEmployee constructor(firstName: String) {

    val firstName: String

    init {
        this.firstName = firstName
    }
}

This can be shortened to

class PEmployee constructor(firstName: String) {
    val firstName: String = firstName
}

And can be even shortened to,

class PEmployee (val firstName: String) {
}

Kotlin has the notion of primary and secondary constructors. init block is not a constructor. It is used in conjunction with primary constructors. It is like an init body for primary constructor.

Multiple constructors

public class JavaEmployee {

    private final String firstName;
    private final boolean fullTime;

    public JavaEmployee(String firstName) {
        this.firstName = firstName;
        this.fullTime = true;
    }

    public JavaEmployee(String firstName, boolean fullTime) {
        this.firstName = firstName;
        this.fullTime = fullTime;
    }

}

The initial equivalent code in Kotlin will be:

class PEmployee (val firstName: String) {
    var fullTime: Boolean = true
    constructor(firstName: String, fullTime: Boolean): this(firstName) {
        this.fullTime = fullTime
    }
}

Which can be even shortened by providing default parameter values, which is something not possible in Java.


class PEmployee (val firstName: String, var fullTime: Boolean = true) {
}

Generate Getters and Setters

There is interesting philosophy of Getters and Setters w.r.t. Kotlin

In Kotlin, getters and setters are automatically generated, however their visibility is same as that of variable visibility.

For ex, if variable is declared private, its getters and setter will be also private, which means you won’t be able to access it from outside the class. Sounds strange and counter-intuitive to Java world. Right?

But that’s how it is.

public class JavaEmployee {

    private final String firstName;
    private  boolean fullTime;

    public JavaEmployee(String firstName) {
        this.firstName = firstName;
        this.fullTime = true;
    }

    public JavaEmployee(String firstName, boolean fullTime) {
        this.firstName = firstName;
        this.fullTime = fullTime;
    }

    public String getFirstName() {
        return firstName;
    }

    public boolean isFullTime() {
        return fullTime;
    }

    public void setFullTime(boolean fullTime) {
        this.fullTime = fullTime;
    }


}

Equivalent code will be

class PEmployee (val firstName: String,  fullTime: Boolean = true) {

    var fullTime = fullTime
    get() {
        println("Running the custom get")
        return field
    }
    set(value) {
        println("Running the custom set")
        field = value
    }
}

Not that getters and setters will be automatically called while referring the variables

fun main () {
    val emp = PEmployee("John")
    println(emp.firstName)
    emp.fullTime = false

    val emp2 = PEmployee("Madhur")
    println(emp2.fullTime);

    val emp3 = PEmployee("Ahuja", false)
    println(emp3.fullTime)
}
John
Running the custom set
Running the custom get
true
Running the custom get
false

Data classes

Data classes are equivalent to POJO

It comes with free equals and toString function, very similar to Lombok

It also comes with a copy function as well.

Extension Functions

Syntactic sugar to extend classes with more functions. It doesn’t actually extend any class.


fun String.upperFirstAndLast() : String {
    val upperFirst = this.substring(0, 1).toUpperCase() + this.substring(1)
    return upperFirst.substring(0, upperFirst.length - 1) +
            upperFirst.substring(upperFirst.length -1, upperFirst.length).toUpperCase()
}

val s = "this is all in lowercase"
println(s.upperFirstAndLast())

Kotlin uses extension functions extensively inside Kotlin Standard Library