Timmy
09/27/2019, 2:41 PMFoo<Nothing?>
(and Foo<Nothing>
) compile to a raw type. While that is fine for the runtime it means losing generic information where it would be normally available (such as in method signatures).
I have found this (https://github.com/JetBrains/kotlin/commit/9acf3e40de2d22318f9d3eda15e5da47117edbc4#diff-efccdee550f101125771902fc631175a) commit that implemented the Nothing -> raw type conversion. I could not find an explanation. Does someone know the reason behind this decision? How could I recover the Nothing generic argument? Is this the only case that compiles to a raw type?dmitriy.novozhilov
09/27/2019, 2:42 PMtschuchort
09/28/2019, 10:12 AMTimmy
09/28/2019, 3:06 PMMethod
into a KFunction
and see the Nothing?
there (I am assuming the Method.kotlinFunction
looks at the metadata?), but down in the Moshi function all that is left is a java.lang.reflect.Type
and a raw class (stemming from Method.getGenericParameterTypes
). Inspecting the metadata there gives only the metadata of the Foo<T>
class with a generic T
. That is already slightly more helpful than before, since now I can actually see that the type has a generic argument; I just don't know what it is (unless I am missing it somewhere). I assume a missing generic parameter type can only be Nothing?
or Nothing
, but I have no way of confirming that (not to mention cases where multiple generic arguments exist).udalov
kotlin.Nothing
in runtime, it's approximated as java.lang.Void
. Since Nothing
is a subtype of all types in Kotlin but Void
doesn't have this property in the JVM, this means potential conflicts of otherwise compatible generic signatures where e.g. covariant return type override is involved: if a superclass method returns List<Foo>
but subclass returns List<Nothing>
, we can only generate the latter as a raw type, to prevent javac or Java reflection from complaining.
Also,
I assume a missing generic parameter type can only beUnfortunately, it's not the only case, the raw type can also come from Java:orNothing?
, but I have no way of confirming that (not to mention cases where multiple generic arguments exist).Nothing
class JavaClass {
static List getRawList() { ... }
}
// foo's JVM type is raw List
fun foo() = JavaClass.getRawList()