为什么Scala原语不会在Java反射中显示为类型参数? [英] Why don't Scala primitives show up as type parameters in Java reflection?
问题描述
case class Foo(
bar: Int,
baz:Boolean,
qux:Option [Int],
quux:Option [Boolean],
quuux:Option [Integer]
)$ b $ println(f.getGenericType)
}
$ c $ c
$ b 产生类似于:
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.TYPE
和 java.lang.Boolean.TYPE
,看起来和普通字段一样吗?
是否有任何方法从 classOf [Foo]
?
scala。< Primitive> eg scala.Int
。它不会将类型存储在Java类文件中,尽管可以这么说。 (或不是;取决于是否需要区分 Int
和 java.lang.Integer
;在即使编译器做得很好,让你相信它是 Int ,那么这个盒装表单就是 java.lang.Integer
)。
无论如何,Scala有其自己的反射功能,它们在不断变化中,但在2.10中,您可以找到 Option的参数 code>类型如下所示: 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
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?
And is there any way to retrieve the primitive type parameters from classOf[Foo]
?
解决方案 Scala thinks that the generic parameter for primitives is scala.<Primitive>
e.g. scala.Int
. It doesn't store the type in the Java class file, though arguably it could. (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
.)
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:
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
这篇关于为什么Scala原语不会在Java反射中显示为类型参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文