HowTo get the class of _ :Any

帅比萌擦擦* 提交于 2019-12-07 11:28:29

问题


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

回答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



回答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



回答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


来源:https://stackoverflow.com/questions/3139854/howto-get-the-class-of-any

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!