Val overriding leads to NPE. Why?


#1

 

Exception in thread “main” java.lang.NullPointerException
     at inner.Rule.<init>(Main.kt:19)
     at inner.ExtRule.<init>(Main.kt:25)
     at inner.InnerPackage$Main$6b8ea04a.main(Main.kt:28)
     at inner.InnerPackage.main(Main.kt:1)
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
     at java.lang.reflect.Method.invoke(Method.java:497)
     at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)


But I expect:

name


Why NPE? How to avoid NPE?


#2

It's because the super constructor Rule gets called before initializing overriden val in ExtRule. Then, println in init block calls virtual property cdx which goes to derived type and, since it is not initialized yet, returns null.

You don’t actually need to override cdx in derived type, instead pass it as parameter to super type:

 
class ExtRule(cdx:ExtCdx):Rule(cdx)

#3

You don't actually need to override cdx in derived type, instead pass it as parameter to super type:

 
class ExtRule(cdx:ExtCdx):Rule(cdx)

In this way cdx have type Cdx but I want that cdx in ExtRule have type ExtCdx.


#4

I see. Well, if you will not use it in init sequence of constructor of superclass (virtual member call in constructor!), everything will be fine with your solution. If you need it, you can use cast:

 
class ExtRule(cdx : ExtCdx) : Rule(cdx) {
    override val cdx: ExtCdx
        get() = super.cdx as ExtCdx
}

#5

 

virtual member call in constructor!

Oh, I dont notice this. (With Kotlin syntax overrided val seems as arguments.) I think more about my hierarchy.