KoxAlen
01/24/2020, 9:57 AMimport java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
import kotlin.reflect.typeOf
data class Definition(
val name: String
)
@ExperimentalStdlibApi
fun main() {
val parsed1: List<Definition> = parseGood("")
val parsed2: List<Definition> = parseBad("")
}
@ExperimentalStdlibApi
private inline fun <reified T> parseGood(blob: String): T {
return readValue(blob)
}
@ExperimentalStdlibApi
private inline fun <reified T> parseBad(blob: String): List<T> {
return readValue(blob)
}
@ExperimentalStdlibApi
private inline fun <reified T> readValue(blob: String): T {
println(typeOf<T>())
val type = object : TypeHolder<T>() {}.type
println(type)
//Do magic with type and return a T
return listOf(Definition("foo")) as T
}
open class TypeHolder<T> protected constructor() {
private var _type: Type
val type get() = _type
init {
val superClass = javaClass.genericSuperclass
_type = (superClass as ParameterizedType).actualTypeArguments[0]
}
}
This prints
kotlin.collections.List<Definition>
java.util.List<? extends Definition>
kotlin.collections.List<Definition>
java.util.List<? extends T>
So for typeOf
T is the same in both cases but for the subclass generation one has the signature with the real type and the other one doesn't.
Is this a bug, or I'm missing something?// ================TestKt$main$$inlined$parseGood$1.class =================
// class version 50.0 (50)
// access flags 0x31
// signature LTypeHolder<Ljava/util/List<+LDefinition;>;>;
// declaration: TestKt$main$$inlined$parseGood$1 extends TypeHolder<java.util.List<? extends Definition>>
and
// ================TestKt$parseBad$$inlined$readValue$1.class =================
// class version 50.0 (50)
// access flags 0x31
// signature LTypeHolder<Ljava/util/List<+TT;>;>;
// declaration: TestKt$parseBad$$inlined$readValue$1 extends TypeHolder<java.util.List<? extends T>>
udalov
java.util.List<? extends T>
looks like a bug, since T
is undeclared at this pointKoxAlen
01/28/2020, 10:18 AM