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:
- Serializable
- Has a no-argument constructor.
- 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:
- Defining a no argument constructor guarantees no-nonsense instantiation.
- Providing getters and setters following a standard naming convention of
get
,set
, andis
allows for frameworks to use reflection without any additional configuration to access properties. - 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.
Top comments (3)
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:
It's not one line, but concise enough to me.
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.
Why not just move
name
andage
to the class body? This way you get a no-arg constructor by default. And you can usewith
orapply
elsewhere in code when instantiatingPerson
.