0

Why does the type conversion from Class[String] to Class[Any] compile successfully ?

object Test extends App {
  var anyClass: Class[Any]    = classOf[Any]
  val strClass: Class[String] = classOf[String]

  /* The following codes compile error: Expression of type Class[String] doesn't conform to expected type Class[Any]. */
  //oClass = sClass

  /* The following codes compile and run successfully. */
  val str2anyClass = strClass.asInstanceOf[Class[AnyRef]]

  println(str2anyClass.toString) // Output: class java.lang.String

}
joymufeng
  • 288
  • 1
  • 7

1 Answers1

2

Why does the type conversion from Class[String] to Class[Any] compile successfully ?

Because Class[A] is invariant in A, and according to Scala specification, your code is invalid.

When you explicitly cast with asInstanceOf, all bets are off and you tell the compiler that you know what you're doing and that it should trust you.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • Thanks for rapid reply. Because Class[String] doesn't conform to Class[Any],asInstanceOf should throw a RuntimeException, but it didn't, why ? – joymufeng Mar 10 '18 at 15:05
  • @joymufeng Because `Class[String]` can be viewed as `Class[AnyRef]`, as `String <: AnyRef`. Don't forget the generic type parameters are erased. – Yuval Itzchakov Mar 10 '18 at 15:06
  • Thanks very much! One more question. Can we do it in java? I find `(Class)strClass` doesn't compile in java. – joymufeng Mar 10 '18 at 15:12
  • @joymufeng `Class objClass = (Class)(Object)String.class;` Why would you want to do this at all? – Yuval Itzchakov Mar 10 '18 at 15:23
  • I'm writing codes like this `value.getClass.asInstanceOf[Class[JValue]]`, `value` could be `JObject` or `JArray` which is subclass of `JValue`. I just want to know how it works. And now it's clear. Thanks for help. – joymufeng Mar 10 '18 at 15:32
  • Funny, `println(List("a", "b").asInstanceOf[List[Int]])` also works. – joymufeng Mar 10 '18 at 15:44
  • 1
    @joymufeng No, it doesn't. Try doing any operation on the casted result and you'll get a runtime exception (again, type erasure). See: https://stackoverflow.com/questions/26089390/why-asinstanceof-doesnt-throw-a-classcastexception – Yuval Itzchakov Mar 10 '18 at 15:48
  • Get it. Thanks again! – joymufeng Mar 10 '18 at 16:03