# Generate Java-Style Builders for Interop

**URL:** <https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422>\
**Category:** Language Design\
**Created:** [March 20, 2017, 9:07pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422 "2017-03-20T21:07:38Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![mike.holler](https://avatars.discourse-cdn.com/v4/letter/m/ecb155/32.png) [@mike.holler](https://discuss.kotlinlang.org/u/mike.holler)\
**Post date:** [March 20, 2017, 9:07pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/1 "2017-03-20T21:07:38Z")

</div>

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:

```auto
class Config(
    val domain: String,
    val port: Int = 443,
    val sslVerify: Boolean = true
)

```

Allows you to optionally specify the `port` and `sslVerify`, falling back to the default value if they do not exist.

```auto
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`.

```auto
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](https://projectlombok.org/features/Builder.html). 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.

Thoughts?

---

<div class="post-metadata">

**Author:** ![mike.holler](https://avatars.discourse-cdn.com/v4/letter/m/ecb155/32.png) [@mike.holler](https://discuss.kotlinlang.org/u/mike.holler)\
**Post date:** [March 20, 2017, 9:12pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/2 "2017-03-20T21:12:13Z")

</div>

I should note that although the above example is contrived and small, this can quickly get out of hand when you have more parameters. I’ve got a class I’d like to convert to Kotlin that has 17 parameters and it’s very unwieldly to call from Java without a builder, but very nice to call from Kotlin.

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [March 20, 2017, 9:13pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/3 "2017-03-20T21:13:23Z")

</div>

In those cases is a constructor really the right solution (even with default parameters)? Remember that ll the parameters are passed to the actual constructor.

---

<div class="post-metadata">

**Author:** ![mike.holler](https://avatars.discourse-cdn.com/v4/letter/m/ecb155/32.png) [@mike.holler](https://discuss.kotlinlang.org/u/mike.holler)\
**Post date:** [March 20, 2017, 9:17pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/4 "2017-03-20T21:17:23Z")

</div>

What else would you propose? It’s my understanding that using a constructor with a lot of default args is the most idiomatic way of replacing the builder pattern in Kotlin, and I’ve yet to see otherwise.

---

<div class="post-metadata">

**Author:** ![mike.holler](https://avatars.discourse-cdn.com/v4/letter/m/ecb155/32.png) [@mike.holler](https://discuss.kotlinlang.org/u/mike.holler)\
**Post date:** [March 20, 2017, 9:18pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/5 "2017-03-20T21:18:07Z")

</div>

I should add that I’d like the final object to be immutable, so converting the `val`s to `var`s won’t work here.

---

<div class="post-metadata">

**Author:** ![pdvrieze](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/pdvrieze/32/1882_2.png) [@pdvrieze](https://discuss.kotlinlang.org/u/pdvrieze)\
**Post date:** [March 20, 2017, 9:20pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/6 "2017-03-20T21:20:56Z")

</div>

I agree with the immutability. In my case I’m using builders. Those are also needed to create copies with arbitrary value changes. I agree it’s ugly. Perhaps generating builders in all cases could be a solution, although I feel that annotation processing (like Lombok) may be a better solution as it doesn’t tie Kotlin to a particular approach (do you copy values, or do you shadow them?).

---

<div class="post-metadata">

**Author:** ![mike.holler](https://avatars.discourse-cdn.com/v4/letter/m/ecb155/32.png) [@mike.holler](https://discuss.kotlinlang.org/u/mike.holler)\
**Post date:** [March 20, 2017, 9:25pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/7 "2017-03-20T21:25:28Z")

</div>

As I understand it, Lombok cannot be used with Kotlin since it relies on a hack to actually generate into the same class that has the annotation (correct me if I’m wrong, I’d love to use Lombok here if possible). All other annotation processing solutions will produce a separate class (e.g., `ConfigBuilder`) outside of the built class (e.g., `Config`) unnecessarily creating a looser coupling than you’d expect.

Additionally, I really think there needs to be an in-language solution for this. I do not think it’s good practice that there is no way to use a constructor’s default value in Java.

---

<div class="post-metadata">

**Author:** ![helpermethod](https://avatars.discourse-cdn.com/v4/letter/h/74df32/32.png) [@helpermethod](https://discuss.kotlinlang.org/u/helpermethod)\
**Post date:** [January 15, 2018, 3:09pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/8 "2018-01-15T15:09:15Z")

</div>

Any news on this? Would love to see something like that implemented as an annotation, like mike.holler proposed. I’m currently developing a Kotlin DSL which is basically unusable from Java because of that problem.

---

<div class="post-metadata">

**Author:** ![mphilipps](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@mphilipps](https://discuss.kotlinlang.org/u/mphilipps)\
**Post date:** [June 14, 2018, 12:46pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/9 "2018-06-14T12:46:01Z")

</div>

I’d also appreciate such a feature. Without it, much of the convenience of especially data classes is lost if being called from Java.

And with data classes, there is another issue: The `copy(...)` method. When being called from Java, you have to provide all the values, effectively making it useless. Maybe the `@JvmBuilder` annotation, or a separate one, could generate a `copyBuilder()` method that returns a builder, prefilled with the attribute values of the copied instance? Creating a copy with a single modified attribute would then look like `myDataClass.copyBuilder().someAttribute("newValue").build()`.

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [June 14, 2018, 1:02pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/10 "2018-06-14T13:02:08Z")

</div>

> [@mike.holler](#):
>
> All other annotation processing solutions will produce a separate class (e.g., `ConfigBuilder` ) outside of the built class (e.g., `Config` ) unnecessarily creating a looser coupling than you’d expect.

If I understand the idea behind the compiler plugins right, this should be possible using a compiler plugin. Sadly they are still a feature without a stable or even public api. I think the JetBrains team mentioned a few times that they are planning to release them at some point but there is no official roadmap for this and I don’t think it has any priority.

---

<div class="post-metadata">

**Author:** ![yetanothermatt](https://avatars.discourse-cdn.com/v4/letter/y/258eb7/32.png) [@yetanothermatt](https://discuss.kotlinlang.org/u/yetanothermatt)\
**Post date:** [September 30, 2018, 3:19pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/11 "2018-09-30T15:19:48Z")

</div>

I wrote an @Builder annotation for Kotlin for exactly this purpose: [GitHub - ThinkingLogic/kotlin-builder-annotation: A minimal viable replacement for the Lombok @Builder plugin for Kotlin code](https://github.com/ThinkingLogic/kotlin-builder-annotation). It’s a standard kapt processor, so unlike Lombok doesn’t mess about with bytecode and therefore clients need to instantiate a new builder, e.g. `new MyDataClassBuilder()`, rather than invoking a static builder method on the class itself (`MyDataClass.builder()`). Otherwise, though, it’s pretty much a drop in replacement for the Lombok builder.

---

<div class="post-metadata">

**Author:** ![Wasabi375](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/wasabi375/32/4741_2.png) [@Wasabi375](https://discuss.kotlinlang.org/u/Wasabi375)\
**Post date:** [September 30, 2018, 3:28pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/12 "2018-09-30T15:28:47Z")

</div>

Cool, looks nice. Have you tried to check whether the class with the `@Builder` annotation has a companion object? You could add an extension to the companion which would return the builder. This however will only work if the class has a companion object already.

---

<div class="post-metadata">

**Author:** ![yetanothermatt](https://avatars.discourse-cdn.com/v4/letter/y/258eb7/32.png) [@yetanothermatt](https://discuss.kotlinlang.org/u/yetanothermatt)\
**Post date:** [September 30, 2018, 9:15pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/13 "2018-09-30T21:15:28Z")

</div>

Thanks 🙂 Nice idea. I hadn’t considered extension functions for companion objects! I’ll have a look when I get the chance (which may not be that soon).

Edit: Sadly it doesn’t seem possible to annotate extension functions with `@JvmStatic`, so Java classes wouldn’t see any such `MyDataClass.builder()` method. It would be visible in Kotlin, but you don’t really need it in Kotlin.

---

<div class="post-metadata">

**Author:** ![carterhudson](https://avatars.discourse-cdn.com/v4/letter/c/bc79bd/32.png) [@carterhudson](https://discuss.kotlinlang.org/u/carterhudson)\
**Post date:** [August 19, 2020, 6:36pm UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/14 "2020-08-19T18:36:39Z")

</div>

Would love native Kotlin support for something like this as an interop feature.

---

<div class="post-metadata">

**Author:** ![werner.altewischer](https://avatars.discourse-cdn.com/v4/letter/w/90db22/32.png) [@werner.altewischer](https://discuss.kotlinlang.org/u/werner.altewischer)\
**Post date:** [March 28, 2024, 9:16am UTC](https://discuss.kotlinlang.org/t/generate-java-style-builders-for-interop/2422/15 "2024-03-28T09:16:41Z")

</div>

We created a KSP version of a builder generator: [GitHub - beatgrid/kodeforge: Support for generation of Kotlin boilerplate code using KSP](https://github.com/beatgrid/kodeforge). It also supports default arguments in the constructor.
