We should be able to write Kotlin code that is reasonably usable from within Java. I think an excellent example of this is extension methods that are called from Java as static helpers with the receiver being the first argument. Kotlin should allow something similarly readable for builders.
I’m well aware we don’t need builders in Kotlin because we can use optional arguments. For example:
class Config( val domain: String, val port: Int = 443, val sslVerify: Boolean = true )
Allows you to optionally specify the
sslVerify, falling back to the default value if they do not exist.
Config("example.com", port = 80)
However, if you try to use Kotlin’s interop with Java and create a
Config inside Java code, all of the default values get lost because everything is required. Even worse, everything is now by argument position rather than keyword, which makes the following really heard to understand without looking at the constructor for
Config config = new Config("example.com", 123, false)
My suggestion is to have a
@JvmBuilder annotation that functions like a stripped down version of Lombok’s
@Builder annotation. Once applied, the Kotlin compiler should generate a Java-style inner
Builder class. This will allow developers to choose where the right place for a Java-style builder is. If a particular code-set will have no Java at all, the developer can decide not to use
@JvmBuilder compilation will proceed as it currently does. When the annotation is used, developers using the class can instantiate it the normal kotlin way (the builder won’t even be usable from Kotlin code) but Java developers will see the builder available to use.