Reified type is erased?

I have written a function with reified generic type:

inline fun <reified T> printType() {
    println(Array<T>::class.java)
    println(Array<String>::class.java)
    println(emptyArray<T>().javaClass)
}

and this is the output when I call:

printType<String>()
/*Output:
class [Ljava.lang.Object;
class [Ljava.lang.String;
class [Ljava.lang.String;
*/

As mentioned in the documents, T will be replaced with String at compile type. So what’s the difference between the first and the second print?

1 Like

::class.java represents java Class, which does not hold generic reference.

1 Like

Most generic type paramters are erased. There is one exception to this, however: Array is compiled to Java array, whose element type is not erased. Read the OPs example closely: Array<String>::class.java evaluated to String[], while Array<T>::class.java evaluated to Object[]. Since T is reified, you would expect it to be treated the same way as a non-parameter type such as String.

To be honest this feels like a kotlin bug. reified should be treated exactly the same as any other type.
I created an issue for it: https://youtrack.jetbrains.com/issue/KT-34815?project=kt

2 Likes
inline fun <reified T> printType() {
    println(T::class.java)
}

Looks like a bug to me. If you really need that class, you can get it like that: arrayOf<T>().javaClass It involves creating new object. You can also use something like Class.forName("[L${T::class.java.name};") which works but looks a bit more cryptic.