scala> class Foo
defined class Foo
scala> object Thing extends Foo
defined module Thing
scala> val set = scala.collection.immutable.Set[Class[_ <: Foo]](Thing.getClass)
<console>:6: error: type mismatch;
found : java.lang.Class[?0] where type ?0
required: Class[_$1] forSome { type _$1 <: Foo }
val set = scala.collection.immutable.Set[Class[_ <: Foo]](Thing.getClass)
^
I'm sure it's probably a java compatibility thing, but shouldn't the class of an object of type T return a class of type Class[T]?
6 comments:
class NiceObject[T <: AnyRef](x : T) {
def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}
implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)
scala> "Hello world".niceClass
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String
However,
Thing.isInstanceOf[Foo]
res10: Boolean = true
The only problem with your code is the syntax. Thing.getClass should be replaced with classOf[Thing], only that doesn't work because Thing is an object. I'm sure there is a way to do what you want, but I don't know how to use classOf with objects.
scala> import scala.reflect.Manifest
import scala.reflect.Manifest
scala> def classOf[T](implicit mfst : Manifest[T]) = mfst.erasure.asInstanceOf[Class[T]]
classOf: [T](implicit scala.reflect.Manifest[T])Class[T]
scala> classOf[String]
res0: Class[String] = class java.lang.String
See #490.
It looks like even THIS solves it:
def classOfObj[T <: AnyRef](x: T) = x.getClass.asInstanceOf[Class[T]]
which confirms this is a scala bug.
Note that it is not correct that (x : T).getClass should return a Class[T]. It should return a Class[_ <: T], as JamesIry posted. Class is invariant, and you might have a subclass.
Post a Comment