Unresolved reference: getSuperclass from Class<*>?


#1

Hi there,

Is there reason why this code won’t compile?

``

//Test.kt
fun main(args : Array<String>) {
  val cls : Class<> = javaClass<Class<>>()
  println(cls.getSuperclass())
}

bash> bin/kotlinc-jvm -output . -src Test.kt
ERROR: /Users/zemian/apps/kotlinc/Test.kt: (3, 15) Unresolved reference: getSuperclass
exec() finished with COMPILATION_ERROR return code

But if I remove explicit type and let it infer, then it compiles fine.

``

val cls = javaClass<Class<*>>()
println(cls.getSuperclass())

So what’s so special about “Class<*>” that it won’t resolve “getSuperclass”?

Thanks,
Zemian


#2

Inferred type for cls is Class<Class<out Any?>> Therefore Class<Class<*>> works fine.

Maybe you wanted to say the following?

val cls:Class<*> = javaClass()
println(cls.getSuperclass())

Unfortunately, getSuperclass is still not available there


#3

Unfortunately, getSuperclass is still not available there

So is this mean there is a bug, or am I still not using it correctly?


#4

Alexander,

To give a more concrete example where this problem occurs, I tried to write a inspect function like this and it won’t compile with the same reason.

fun main(args : Array<String>) {   val cls = Class.forName(args[0])   inspect(cls) } fun inspect(cls : Class<*>?, indent : Int = 0) {   if (cls == null)           return

  val prefix = " “.repeat(indent)
  println(”${prefix}Class: cls") &nbsp;&nbsp;for (c in cls.getInterfaces()) &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;println("{prefix}Interface: $c")

  inspect(cls.getSuperclass(), indent + 2)
}

Can you show me the correct way to make it compilable?

Also, after reading your comments, I have another question. What’s different if I change the method declaration to the following vs above?

fun inspect(cls : Class<out Any?>?, indent : Int = 0) { ... }

Thanks,
Zemian


#5

The problem with inability to call getSuperclass() on variable with type Class<*> is a bug. I have already posted it to tracker: KT-3194. An issue doesn't mention java.lang.Class, but emulates the situation with pure kotlin.

As a workaround you can explicitly convert your cls variable to Class<Any>:

``

fun inspect(cls : Class<*>?, indent : Int = 0) {
  if (cls == null) return
  // …
  inspect((cls as Class<Any>).getSuperclass(), indent + 2)
}


#6

Class<*> is an alias for Class<out Any?>, so nothing should be changed after replacement.


#7

Thanks Nickolay!

The explicit cast works, but compiler will spit a warn:

Unchecked cast: java.lang.Class<out jet.Any?>? to java.lang.Class<jet.Any>

How do I properly cast without the warning? (I tried "Class<Any?>" and I get the same WARN.)

Interestingly if I cast it as “Class<out Any?>”, I will also get the “Unresolved reference getSuperclasss()” error! I hope this helps your bug ticket in doing more through testing.