I am creating a TypeToken
-like system similar to what Gson has and I have stumbled upon something I do not understand.
The intention with this code would be to have only one TypeReference
class with one generic argument that could hold multiple ones. The class would be created using inline
function, this way the user does not need to know of the Holder
class.
Please consider the code below:
package testing
import java.lang.reflect.ParameterizedType
import java.lang.reflect.Type
abstract class TypeReference<T : Holder> {
val type: Type = (javaClass.genericSuperclass as ParameterizedType).actualTypeArguments[0]
override fun toString(): String {
return type.typeName
}
}
inline fun <reified T : Holder> create() = object : TypeReference<T>() {}
inline fun <reified WHAT> createSingle() = object : TypeReference<Single<WHAT>>() {}
class Foo
interface Holder
interface Single<T> : Holder
fun main(args: Array<String>) {
println(create<Single<HashMap<Int, String>>>())
println(create<Single<Foo>>())
println(createSingle<HashMap<Int, String>>())
println(createSingle<Foo>())
}
This is the output:
testing.Single<java.util.HashMap<java.lang.Integer, java.lang.String>>
testing.Single<testing.Foo>
testing.Single<WHAT>
testing.Single<WHAT>
It looks like to me as if the Single<WHAT>
(sry for that generic name) does not get 'truly' inlined and some intermediate name gets generated.
I have also looked in the docs but I did not find examples regarding this.
How can I create what I initially intended to do? Why does this happen?
Edit.:
I wanted to create an issue, but they already know about this.
A very similar issue is issued here which is said to be a duplicated of this. You can also vote in the latter link.
For future reference: Kotlin 1.2.50
is used here.
I decompile this code,found some different between two func
private static final TypeReference create() {
Intrinsics.needClassReification(); <---- here
return (TypeReference)(new TypeReference() {
});
}
private static final TypeReference createSingle() {
return (TypeReference)(new TypeReference() {
});
}
And manual add this code, work fine. Don't known too much about this, no document found.
inline fun <reified WHAT > createSingle() = Intrinsics.needClassReification().let {
object : TypeReference<Single<WHAT>>() {}
}
result:
Single<java.util.HashMap<java.lang.Integer, java.lang.String>>
Single<Foo>
Single<java.util.HashMap<java.lang.Integer, java.lang.String>>
Single<Foo>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With