# Using secondary constructors is not recommended? Or is it?

**URL:** <https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021>\
**Category:** Language Design\
**Created:** [October 25, 2018, 6:54pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021 "2018-10-25T18:54:09Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![spelta](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/spelta/32/5620_2.png) [@spelta](https://discuss.kotlinlang.org/u/spelta)\
**Post date:** [October 25, 2018, 6:54pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/1 "2018-10-25T18:54:09Z")

</div>

I am following the Kotlin course at Udacity: [Kotlin Bootcamp for Programmers | Udacity Free Courses](https://eu.udacity.com/course/kotlin-bootcamp-for-programmers--ud9011)

The lesson about classes shows how to use secondary constructors, but then **strongly recommends _not_ to use them** , and to favor creating a top-level function that would return an object instead.

I’ve seen that secondary constructors have been removed and reintroduced in Kotlin.  
So, is there a kind of official recommendation about how to deal with multiple ways to build an object?

---

<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:** [October 25, 2018, 9:14pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/2 "2018-10-25T21:14:40Z")

</div>

I don’t know why you should not use secondary constructors. Does this course give a reason why not to use them?

---

<div class="post-metadata">

**Author:** ![spelta](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/spelta/32/5620_2.png) [@spelta](https://discuss.kotlinlang.org/u/spelta)\
**Post date:** [October 25, 2018, 9:27pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/3 "2018-10-25T21:27:45Z")

</div>

It says it is just not good practice; and to exploit Kotlin named arguments with default parameters to achieve what used to be done with several constructors in Java. Then adds that if you need anything specific, to prefer that way I described rather than a secondary constructor. Meh. I’m puzzled.

---

<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:** [October 25, 2018, 10:14pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/4 "2018-10-25T22:14:33Z")

</div>

In general you should not create overloads of functions or secondary constructors just so you can have default arguments.

```kotlin
class DontDoThis(val a: Int) {
    constructor() : this(5) 
}

```

I guess this is obvious. But something like this is fine IMO

```kotlin
class Foo(val bar: Bar) {
    constructor (someState: State): this(someState.calculateBar()) {
        // TODO get some other data from state
    }
}

```

In general you won’t need secondary constructors often. The one situation where I use them regularly is the scenario above.

---

<div class="post-metadata">

**Author:** ![tieskedh](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/tieskedh/32/2816_2.png) [@tieskedh](https://discuss.kotlinlang.org/u/tieskedh)\
**Post date:** [October 26, 2018, 12:43am UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/5 "2018-10-26T00:43:31Z")

</div>

I almost never use secondary constructors, nor init-blocks.In my classes are the logic that either update the fields or queries the fields.

If you would use a class A almost always to construct another class B, I add a function to class A that constructs class B and I would put the logic of construction in A.

If the classes are more stand-alone, so they are very tight to their fields, I most of the time would create top-level extension-functions.

In either way, you can write the code fluently.  
And I almost never put a lambda in a constructor, unless it stores the lambda.  
I would much rather prefer to use it in a top-level function.

In this case, I would probably put an extension-function inside FooKt:

```
fun State.buildFoo() = Foo(calculateBar()).apply{
//do something.
}

```

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [October 26, 2018, 6:59am UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/6 "2018-10-26T06:59:38Z")

</div>

Secondary constructors are not officially discouraged, but in my practice, it looks ugly and is not really needed in kotlin, so I would agree, it is better to avoid them. The general way for alternative builders is a builder function in companion object. The only case, when secondary constructor makes sense is when you use it a lot and it is more concise to write `MyType(...)` instead of `MyType.build(...)`.

---

<div class="post-metadata">

**Author:** ![fatjoe79](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fatjoe79/32/4221_2.png) [@fatjoe79](https://discuss.kotlinlang.org/u/fatjoe79)\
**Post date:** [October 26, 2018, 12:42pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/7 "2018-10-26T12:42:04Z")

</div>

I agree with @tieskedh. I never encountered a situation, where I would prefer a secondary constructor over other means.

---

<div class="post-metadata">

**Author:** ![medium](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/medium/32/10404_2.png) [@medium](https://discuss.kotlinlang.org/u/medium)\
**Post date:** [October 26, 2018, 2:04pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/8 "2018-10-26T14:04:02Z")

</div>

@darksnake There is no need to write `build` (or `create` …) since you can use the `invoke` operator function.

```auto
fun main() {
    val d = Demo(1, 2)
    println(d)
}

data class Demo(val x: Int) {
    companion object {
        operator fun invoke(x: Int, y: Int) = Demo(x + y)
    }
} 

```

[https://pl.kotl.in/SkWjA9xnX](https://pl.kotl.in/SkWjA9xnX)

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [October 26, 2018, 2:09pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/9 "2018-10-26T14:09:02Z")

</div>

Wow! Thanks. I’ve missed that possibility. I usually miss some usage of `invoke`.

---

<div class="post-metadata">

**Author:** ![Eliote](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/eliote/32/7934_2.png) [@Eliote](https://discuss.kotlinlang.org/u/Eliote)\
**Post date:** [October 26, 2018, 2:45pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/10 "2018-10-26T14:45:51Z")

</div>

What is the advantage of that over this?

```auto
data class Demo(val x: Int) {
	constructor(x: Int, y: Int): this(x + y)
}

```

---

<div class="post-metadata">

**Author:** ![roryaburks](https://avatars.discourse-cdn.com/v4/letter/r/67e7ee/32.png) [@roryaburks](https://discuss.kotlinlang.org/u/roryaburks)\
**Post date:** [October 26, 2018, 4:17pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/11 "2018-10-26T16:17:25Z")

</div>

I suppose I can see why someone would suggest that especially when things like data classes and primary constructors exist. You would want class constructors to reflect the necessary and sufficient parameters that a class needs, and functions which convert different data sets and data feeds into those necessary and sufficient parameters should be semantically separate from the constructors.

Personally I’ve been using the companion object for a lot of these means:

```auto
class Image(private val data: IntArray, val width: Int, val height: Int) {
    ...

    companion object {
        fun FromFile( val filePath: String) : Image {
           ....
        }
    }
}

```

---

<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:** [October 27, 2018, 7:50pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/12 "2018-10-27T19:50:33Z")

</div>

From my perspective there are two main points to consider: Java compatibility and semantics. First semantics, is the constructor mainly a general purpose way of creating the object as if it was calling the constructor, then I would go for secondary if possible, or operator invoke() / toplevel otherwise (operator invoke allows for better Java compatibility). If it is fundamentally a factory function that may return different types then use a factory. Java compatibility is why I prefer a secondary constructor as it works as-designed. In case of inheritance secondary constructors can be invoked by the children, primary ones cannot.

---

<div class="post-metadata">

**Author:** ![mice777](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/mice777/32/4560_2.png) [@mice777](https://discuss.kotlinlang.org/u/mice777)\
**Post date:** [October 31, 2018, 9:13am UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/13 "2018-10-31T09:13:01Z")

</div>

Advantage of `invoke` is that before calling class constructor, you can calculate things, have local variables, call some functions, etc.  
While in case of secondary constructor, the first thing you must do is calling primary constructor, so there’s little space for some code.

```auto
data class Demo(val x: Int) {
    companion object {
        operator fun invoke(x: Int, y: Int): Demo{
            val v = someCalculation(x, y)
            return Demo(v)
        }
    }
} 

```

---

<div class="post-metadata">

**Author:** ![Eliote](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/eliote/32/7934_2.png) [@Eliote](https://discuss.kotlinlang.org/u/Eliote)\
**Post date:** [October 31, 2018, 1:28pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/14 "2018-10-31T13:28:02Z")

</div>

Sure, but for simple cases the secondary constructor looks better(IMO) and might be better for compatibility as @pdvrieze pointed out. So I think secondary constructors are perfectly fine, and not discouraged.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [November 1, 2018, 7:28pm UTC](https://discuss.kotlinlang.org/t/using-secondary-constructors-is-not-recommended-or-is-it/10021/15 "2018-11-01T19:28:32Z")

</div>

Definitely no rules here. It’s just that I found that I removed almost all secondary constructors after migrating java code to kotlin. Not intentionally, it just looked better.
