scala - 为什么Scala原语不会在Java反射中显示为类型参数?

标签 scala generics reflection

给定以下案例类:

case class Foo(
    bar: Int,
    baz: Boolean,
    qux: Option[Int],
    quux: Option[Boolean],
    quuux: Option[Integer]
)

我期望以下几点:

for (f <- classOf[Foo].getDeclaredFields) {
    println(f.getGenericType)
}

产生类似:
int
boolean
scala.Option<int>
scala.Option<boolean>
scala.Option<java.lang.Integer>

但是,它产生:
int
boolean
scala.Option<java.lang.Object>
scala.Option<java.lang.Object>
scala.Option<java.lang.Integer>

为什么为什么要从泛型中删除基元,而不是像普通字段中那样将其视为java.lang.Integer.TYPEjava.lang.Boolean.TYPE呢?

有没有办法从classOf[Foo]检索基本类型参​​数?

最佳答案

Scala认为基元的通用参数是scala.<Primitive>,例如scala.Int。尽管可以这样,但它没有将类型存储在Java类文件中。 (或是否;取决于Intjava.lang.Integer之间是否需要区别;在幕后,装箱的格式是java.lang.Integer,即使编译器做得很好,使您相信它是Int。)

无论如何,Scala都有自己的反射功能,这些功能会不断变化,但是在2.10中,您可以找到Option类型的参数,如下所示:

import scala.reflect.runtime.universe._
typeTag[Foo].tpe.members.collect{
  case m: MethodSymbol if m.isCaseAccessor => m 
}.foreach(m => println(m.name + " " + m.typeSignature))

你会得到类似的东西
quuux => scala.Option[java.lang.Integer]
quux => scala.Option[scala.Boolean]
qux => scala.Option[scala.Int]
baz => scala.Boolean
bar => scala.Int

关于scala - 为什么Scala原语不会在Java反射中显示为类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20749536/

相关文章:

scala - 如何使用 Spark 在 map() 中快速从 HDFS 读取文件

reflection - 无法在PowerShell中加载.NET类型

java - 如何通过反射读取 Javadoc 注释?

scala - 如何将方法的返回类型与 Scala native 或 TypeTag 进行比较?

java - 将 Builder 扩展/子类化到直接子级之外

java - 对 Java 集合使用泛型的意外行为

scala - 如何比较 Scala 特征中的有序抽象类型?

scala - 从光滑的查询中获取所有实体

scala - 类型与类型投影不匹配

java - 是否可以创建类型参数为 Class<T> 的泛型类