Watu
Watu

Reputation: 63

"Property must be initialized or be abstract" in init block when throwing an exception

Why does kotlin report Property must be initialized or be abstract. The object construction is never finished, so it should not matter whether a is initialized or not. Could a case be demonstrated where this would be a problem?

class Foo {
    private val a: Int

    init {
        a = 42
        throw Exception()
    }
}

fun main() {
    Foo()
}

kotlin playground


However these work just fine

fun bar() {
    throw Exception()
}

class Foo {
    private val a: Int

    init {
        a = 42
        bar()
    }
}

fun main() {
    Foo()
}

kotlin playground

class Foo {
    private val a: Int = throw Exception()
}

fun main() {
    Foo()
}

kotlin playground


Similar java code works as expected:

public class Test {
    private static class Foo {
        private final int a;

        public Foo() throws Exception {
            a = 42;
            throw new Exception();
        }
    }

     public static void main(String []args) throws Exception {
         new Foo();
     }
}

Upvotes: 3

Views: 3222

Answers (3)

Watu
Watu

Reputation: 63

It seems to be a compiler bug as Alexey suggested
There is similar issue posted on Kotlin bug tracer.

Upvotes: 0

Alexey Romanov
Alexey Romanov

Reputation: 170745

Similar java code works as expected:

Java initializes fields to 0 (or null/false depending on type) by default. You can see it e.g. by printing a's value before the a = 42 line.

Kotlin doesn't, because this implicit initialization makes it too easy to forget to initialize a property and doesn't provide much benefit. So it requires you to initialize all properties which have backing fields.

Upvotes: 1

Arpan Kanthal
Arpan Kanthal

Reputation: 503

The question is very well answered in the below link.
Kotlin: why do I need to initialize a var with custom getter?

Essentially it boils down to having a backing field for every "val" (property) . If you can provide a backing field, you need not initialize the field. Below is a small example of it.

class Foo {
    private val a: Int
    get() = getValue()

}

fun getValue():Int {
    throw Exception()
}

fun main() {
    Foo()
}

Upvotes: 0

Related Questions