Tutorial :HowTo get the class of _ :Any



Question:

I've wrapped a Message and would like to log which message I've wrapped.

val any :Any = msg.wrappedMsg  var result :Class[_] = null  

The only solution I could find is matching everything:

result = any match {    case x:AnyRef => x.getClass    case _:Double => classOf[Double]    case _:Float  => classOf[Float]    case _:Long   => classOf[Long]    case _:Int    => classOf[Int]    case _:Short  => classOf[Short]    case _:Byte   => classOf[Byte]    case _:Unit   => classOf[Unit]    case _:Boolean=> classOf[Boolean]    case _:Char   => classOf[Char]  }  

I wonder if there's a better solution? The following 2 approaches do not work :(

result = any.getClass //error  // type mismatch;  found   : Any  required: ?{val getClass: ?}   // Note: Any is not implicitly converted to AnyRef.    // You can safely pattern match x: AnyRef or cast x.asInstanceOf[AnyRef] to do so.  result = any match {    case x:AnyRef => x.getClass    case x:AnyVal => /*voodoo to get class*/ null // error  }  //type AnyVal cannot be used in a type pattern or isInstanceOf  


Solution:1

You can safely call .asInstanceOf[AnyRef] on any Scala value, which will box primitives:

scala> val as = Seq("a", 1, 1.5, (), false)  as: Seq[Any] = List(, 1, 1.5, (), false)    scala> as map (_.asInstanceOf[AnyRef])  res4: Seq[AnyRef] = List(a, 1, 1.5, (), false)  

From there, you can call getClass.

scala> as map (_.asInstanceOf[AnyRef].getClass)  res5: Seq[java.lang.Class[_]] = List(class java.lang.String, class java.lang.Int  eger, class java.lang.Double, class scala.runtime.BoxedUnit, class java.lang.Boo  lean)  

Tested with 2.8.0.RC6, I don't know it this worked in 2.7.7.

Definitely new in 2.8 are the companion objects for the classes derived from AnyVal. They contain handy box and unbox methods:

scala> Int.box(1)  res6: java.lang.Integer = 1    scala> Int.unbox(res6)  res7: Int = 1  


Solution:2

Won't casting just do the trick, as suggested in the error message?

  scala> val d:Double = 0.0  d: Double = 0.0    scala> d.asInstanceOf[AnyRef].getClass  res0: java.lang.Class[_] = class java.lang.Double  


Solution:3

As of scala 2.10.0, getClass is available on Any (and not just on AnyRef), so you don't need to do any contorsion anymore and can just do any.getClass.

Note though that you still must be prepared to handlet the dual relation between primitive types and their boxed version. By example getClass on an integer value will return either java.lang.Integer.TYPE (the class of the primitive Int type) or classOf[java.lang.Integer] depending on the static type of the value:

scala> 123.getClass  res1: Class[Int] = int    scala> val x : Int = 123  x: Int = 123    scala> x.getClass  res2: Class[Int] = int    scala> val x: AnyVal = 123  x: AnyVal = 123    scala> x.getClass  res3: Class[_] = class java.lang.Integer    scala> val x: Any = 123  x: Any = 123    scala> x.getClass  res4: Class[_] = class java.lang.Integer  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »