开发者

HowTo get the class of _ :Any

开发者 https://www.devze.com 2023-01-04 22:07 出处:网络
I\'ve wrapped a Message and would like to log which message I\'ve wrapped. val any :Any = msg.wrappedMsg

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.getClas开发者_如何学Cs //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


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


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


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
0

精彩评论

暂无评论...
验证码 换一张
取 消