Scala:转换为运行时类实例

时间:2014-04-01 01:35:02

标签: scala

请参阅以下代码段:

def getObject(key: String, cacheName: String)(clazz: Class[_ <: ICacheable]) = {
   Option(icacheFactory.getCache(cacheName).get(key).asInstanceOf[clazz])      
}

编译器抱怨asInstanceOf[clazz]

基本上我要做的是将从icacheFactory.getCache(cacheName).get(key)返回的ICacheable转换为clazz实例

我该如何解决这个问题?看来asInstanceOf只支持静态类型

2 个答案:

答案 0 :(得分:2)

直括号“[]”表示类型参数 - 您必须为asInstanceOf提供类型,而不是像clazz这样的值。此外,asInstanceOf永远不会返回null,而是在无法进行强制转换时抛出异常,因此请将其包含在Try而不是Option中。以下是您的功能的重写版本:

def getObject[A <: ICacheable](key: String, cacheName: String) = {
  Try(icacheFactory.getCache(cacheName).get(key).asInstanceOf[A])
}

与需要传递Class个对象的丑陋需求的Java代码不同,在Scala中,类型推断可能使得甚至不必指定类型参数:

def f(x: SubclassOfICacheable) = ???

getObject("cache", "key") map f

Scala可以推断出A应该是SubclassOfICacheable而不需要明确指定它。

答案 1 :(得分:2)

最接近您的解决方案是

def getObject(key: String, cacheName: String)(clazz: Class[_ <: ICacheable]) =
   Try(clazz.cast(icacheFactory.getCache(cacheName).get(key)))

cast的{​​{3}} javadoc)。如果您在编译时知道所需的类而不是从外部接收它(例如,作为字符串或来自客户端代码的Class),则可以避免使用Class显式传递类:

def getObject[T <: ICacheable](key: String, cacheName: String)(implicit tag: ClassTag[T]) =
   Try(tag.runtimeClass.cast(icacheFactory.getCache(cacheName).get(key)))

您可以按如下方式调用它:

getObject[SomeCacheable](key, cacheName)

对于第一个版本:

getObject(key, cacheName)(classOf[SomeCacheable])