请参阅以下代码段:
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只支持静态类型
答案 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])