简体   繁体   English

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

[英]Why don't Scala primitives show up as type parameters in Java reflection?

Given the following case class: 给出以下案例类:

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

I would expect the following: 我希望如下:

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

to produce something like: 产生类似的东西:

int
boolean
scala.Option<int>
scala.Option<boolean>
scala.Option<java.lang.Integer>

But instead, it produces: 但相反,它产生:

int
boolean
scala.Option<java.lang.Object>
scala.Option<java.lang.Object>
scala.Option<java.lang.Integer>

Why do the primitives get erased from the generics, instead of getting treated as java.lang.Integer.TYPE and java.lang.Boolean.TYPE , as appears to happen with the plain fields? 为什么原语会从泛型中删除,而不是被视为java.lang.Integer.TYPEjava.lang.Boolean.TYPE ,就像普通字段一样?

And is there any way to retrieve the primitive type parameters from classOf[Foo] ? 有没有办法从classOf[Foo]检索原始类型参数?

Scala thinks that the generic parameter for primitives is scala.<Primitive> eg scala.Int . Scala认为基元的通用参数是scala.<Primitive>例如scala.Int It doesn't store the type in the Java class file, though arguably it could. 它不会将类型存储在Java类文件中,尽管可以说它可以。 (Or not; depends on whether there needs to be a distinction between Int and java.lang.Integer ; under the hood the boxed form is java.lang.Integer , even if the compiler does a good job making you believe it is Int .) (或者不是;取决于是否需要区分Intjava.lang.Integer ;框内形式是java.lang.Integer ,即使编译器做得很好,你也相信它是Int 。 )

Anyway, Scala has its own reflection capabilities which are in flux, but with 2.10 you can find the arguments of the Option types like so: 无论如何,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))

and you'll get something like 你会得到类似的东西

quuux => scala.Option[java.lang.Integer]
quux => scala.Option[scala.Boolean]
qux => scala.Option[scala.Int]
baz => scala.Boolean
bar => scala.Int

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM