user140327
user140327

Reputation:

Kotlin Constructor syntax design rationale?

These two classes seem to me to behave identically:

class A constructor(ii_: Int) {
    var ii = 0
    var xx = 0.0F
    var msg = ""
    init {
        ii = ii_
        xx = ii + 42.0F
        msg = "The value of ii is $ii and the value of xx is $xx"
    }
    
    fun display() {
        print("A.display() $ii, $xx\n")
        print("A.display() $msg\n")
    }
    
}


class C {
    var ii = 0
    var xx = 0.0F
    var msg = ""
    constructor(ii_: Int) {
        ii = ii_
        xx = ii + 42.0F
        msg = "The value of ii is $ii and the value of xx is $xx"
    }
    
    fun display() {
        print("C.display() $ii, $xx\n")
        print("C.display() $msg\n")
    }
    
}

If I am not going to have more than one constructor then is there an advantage to the version that uses a primary constructor?

Is there a theoretical reason that I am not seeing for the primary ctor + init block scheme?

The primary constructor version with it's init block seems baroque, which makes me think there is a deeper reason for it, but I can't see it.

I am aware my class A does not strictly need the constructor keyword. That is not what I am asking, please do not bother telling me I don't need it.

Upvotes: 1

Views: 55

Answers (1)

gidds
gidds

Reputation: 18577

init blocks are more like property initialisers than constructors.  (If you know Java, they're pretty much the same as Java's instance initialisers; see this question, and this discussion.)  The major issues are:

  • You can have multiple init blocks; they all run, in order (along with property initialiser expressions).  If you use them for initialising properties, you can put them right next to their property, for clarity.

  • They run for every constructor, so you don't need to duplicate code between constructors, or risk forgetting.  (They run, along with property initialisers, after the call to the superclass constructor but before the rest of the constructor body.)

  • They can be used in object expressions and declarations, where a constructor isn't allowed.  (They were originally introduced into Java for the equivalent of this, i.e. anonymous classes.)

  • If there's a primary constructor, then they have access to its parameters (though not to those of any secondary constructor).  (This makes them more powerful than Java's instance initialisers.)

Upvotes: 0

Related Questions