scala - 使用 classManifest 提供具有上限类型界限的 Class 对象

标签 scala generics manifest type-erasure

假设我需要提供一个带有 java.lang.Class 对象的方法,该对象表示某个父类 A 的子类。我需要从另一个方法执行此操作,该方法具有一个通用参数,其上限类型绑定(bind)到 A

我认为这可能有效:

class A
def f(clazz: java.lang.Class[_ <: A]) = ()
def g[T <: A : Manifest] = f(classManifest[T].erasure)

但事实并非如此:

<console>:9: error: type mismatch;
 found   : java.lang.Class[_$1(in method g)] where type _$1(in method g)
 required: java.lang.Class[_ <: A]
         def g[T <: A : Manifest] = f(classManifest[T].erasure)
                                                       ^

为什么编译器无法判断出 T 实际上是 A 的子类?有什么我可以帮忙的吗?或者我应该以完全不同的方式处理这个问题?

最佳答案

它不起作用,因为 erasure has the type Class[_] ,这是一种存在类型。这意味着Class对象erasure由某种类型参数化,但具体是哪种类型并不重要。 erasure没有类型 Class[T]如上所述。

方法f需要 Class[_ <: A] 类型的参数这是已知为 A 子类型的某种类型。 Class[_] 不一定能保证这个上限。在上面输入。

解决方案:您知道 erasure有一个正确的类型,只是这个类型没有在ClassManifest中公开目的。只需转换它即可:

classManifest[T].erasure.asInstanceOf[Class[A]]

编辑:

如果你有一个子类BA :

scala> class A

scala> def f(clazz: java.lang.Class[_ <: A]) = ()

scala> def g[T <: A : Manifest] = f(classManifest[T].erasure.asInstanceOf[Class[A]])

scala> g[A]

scala> class B extends A

scala> g[B]

关于scala - 使用 classManifest 提供具有上限类型界限的 Class 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11354427/

相关文章:

generics - 是否可以在when语句中返回与类型参数相同的类型

java - 方法(E[])不适用于参数(int[])

android - 我遇到了 Android Manifest 合并问题,提示我更新到 26.1.0。我尝试了一下,它说该软件包不可用

android - 如何通过显式创建 AndroidManifest.xml 来创建 android 应用程序?

Scala 如何将 List 的等值元素放入子列表中

scala - 在 Scala 中重写,按数组类型区分的重载 Java 方法

Scala 相当于 Haskell 的 insertWith for Maps

scala - 如何过滤 Spark Dataframe 的 MapType 字段?

vb.net - T 类型未定义

java - 错误 :(15) Tag <uses-permission> attribute name has invalid character ' ' . Android list