loading...

Kotlin: No more boilerplate in my POJOs

cr0wst profile image Steve Crow Originally published at smcrow.net on ・3 min read

Kotlin is very quickly becoming one of my all-time favorite languages to play with. It is a JVM language that offers static typing, built-in null safety, and some powerful syntactic sugar that helps mitigate some of the bloat commonly found in Java applications.

I would like to highlight some of my favorite features in a series of short blog posts.

The POJO

The POJO, short for P lain O ld J ava O bject, is a base-line object not bound to any specific framework or library. It should not go out of its way to implement any interfaces or extend any classes. Some would say that it should also not have any specialized annotations such as @JsonProperty or @Entity. I am willing to sacrifice strictness in the definition for the flexibility that these annotations provide.

The JavaBean

The JavaBean goes a step further and is:

  1. Serializable
  2. Has a no-argument constructor.
  3. Properties are accessed via getters and setters which follow a standard naming convention.

While technically POJOs, the JavaBean specification does require implementation of the serializable interface. This breaks the anti-interface agenda of the POJO brigade.

An example bean; note that the no-argument constructor is provided as long as no other constructors are defined:

class Person implements Serializable {
    protected String name;

    protected int age;

    public int getAge() {
        return age;
    }

    public String getName() {
        return name;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Critics, and developers, of Java will tell you that it is a wordy mess of classes and boilerplate definitions. They’re not wrong; Java can be a wordy mess of classes and boilerplate definitions. However, the bean specification has some advantages:

  1. Defining a no argument constructor guarantees no-nonsense instantiation.
  2. Providing getters and setters following a standard naming convention of get, set, and is allows for frameworks to use reflection without any additional configuration to access properties.
  3. Keeping the class simple means that it can be reusable without any knowledge of weird dependencies.

The Kotlin POJO

Kotlin streamlines the POJO process by including a lot of the boilerplate code automatically. The same POJO can be declared as:

class Person(var name: String = "", var age: Int = 0) : Serializable

Classes are declared in a similar way to Java by using the class keyword. However, instead of using implements or extends to declare an interface or parent class; we put the interfaces after a :. Additionally, notice that the type of property is declared after the property. This is because type declaration is optional if the type can be inferred.

Constructor Fields

Kotlin allows you to declare fields inside of the class declaration in lue of having a constructor like this:

public Person(String name, int age) {
    this.name = name;
    this.age = age;
}

This constructor is generated automatically for you. However, a no-argument constructor is not generated, unless you specify default values for the properties. If we were to declare the class as:

class Person(var name: String, var age: Int) : Serializable

only the above constructor would be created.

The JavaBean specification requires a no-argument constructor, so default values need to be provided. This can pose some issues when working with a framework like JPA which expects a no-argument constructor. There are some plugins for Kotlin that will create this constructor for you without specifying the default values.

See: Kotlin Compiler Plugins: No-Arg Compiler Plugin

Getters and Setters

Getters and setters are also automatically created, and they are utilized internally when working directly with the properties. Make note that Kotlin provides two initialization keywords, var and val. Properties that are immutable (or final) should be declared with val; Kotlin will generate only a getter for immutable properties.

Conclusion

I am a firm believer in minimizing the amount of wordy boilerplate being added to my code. If it is something that is expected, and my IDE can automate it, why can’t my language do the same? Kotlin not only does this for me, but it also does it in such a way that is easy to understand when migrating from Java. None of these concepts are unnecessarily foreign; with the end result being short, easy to read, code.

Discussion

pic
Editor guide
Collapse
stealthmusic profile image
Jan Wedel

Although I like Kotlin because of great features like Coroutines, Pojos are not the key feature to me. This has been solved with Lombok in Java:

@Data
class Person {
    private String name;
    private int age;
}

It's not one line, but concise enough to me.

Collapse
erikthered profile image
Erik Nelson

I will agree that there are definitely more compelling features in Kotlin than data classes. However, it feels cleaner being built into the language versus having to include Lombok's annotation processor.

Collapse
serhuz profile image
Sergei Munovarov

Why not just move name and age to the class body? This way you get a no-arg constructor by default. And you can use with or apply elsewhere in code when instantiating Person.