scala - 使用 Scala 反射从对象中获取原始字段的类型
问题描述
因此,我试图获取 Scala 对象类中每个字段的类型:
package myapp.model
object MyObject {
val theInt: Option[Int]
}
使用 Brian 在这篇文章中提供的 ReflectionHelper 。我使用getFieldType
但它返回Option[Object]
而不是它是什么,即Option[Int]
. 该答案中的示例代码适用于案例类,例如:
package myapp.model
case class Person(
name: String,
age: Option[Int]
)
scala> ReflectionHelper.getFieldType("myapp.model.Person", "age") // int
res12: Option[reflect.runtime.universe.Type] = Some(Option[Int])
但是,如果我getFieldType
在 Scala 对象字段上运行,我们会得到:
scala> ReflectionHelper.getFieldType("myapp.model.MyObject$", "theInt")
res10: Option[reflect.runtime.universe.Type] = Some(Option[Object])
导致这种行为的 Scala 对象有什么不同,我怎样才能getFieldType
返回Option[Int]
而不是Option[Object]
像 case 类那样返回?
为方便起见,这是另一个问题的 ReflectionHelper:
import scala.reflect.runtime.{ universe => u }
import scala.reflect.runtime.universe._
object ReflectionHelper {
val classLoader = Thread.currentThread().getContextClassLoader
val mirror = u.runtimeMirror(classLoader)
def getFieldType(className: String, fieldName: String): Option[Type] = {
val classSymbol = mirror.staticClass(className)
for {
fieldSymbol <- classSymbol.selfType.members.collectFirst({
case s: Symbol if s.isPublic && s.name.decodedName.toString() == fieldName => s
})
} yield {
fieldSymbol.info.resultType
}
}
def maybeUnwrapFieldType[A](fieldType: Type)(implicit tag: TypeTag[A]): Option[Type] = {
if (fieldType.typeConstructor == tag.tpe.typeConstructor) {
fieldType.typeArgs.headOption
} else {
Option(fieldType)
}
}
def getFieldClass(className: String, fieldName: String): java.lang.Class[_] = {
// case normal field return its class
// case Option field return generic type of Option
val result = for {
fieldType <- getFieldType(className, fieldName)
unwrappedFieldType <- maybeUnwrapFieldType[Option[_]](fieldType)
} yield {
mirror.runtimeClass(unwrappedFieldType)
}
// Consider changing return type to: Option[Class[_]]
result.getOrElse(null)
}
}
解决方案
尝试
// import scala.reflect.runtime.universe._
mirror.staticClass("myapp.model.Person").typeSignature.member(TermName("age")).typeSignature // => Option[Int]
mirror.staticModule("myapp.model.MyObject").typeSignature.member(TermName("theInt")).typeSignature // => Option[Int]
推荐阅读
- javascript - 异步函数设置变量
- sql - 如何将 [MM DD YYYY hh:mm:ss:mmm(AM/PM)] 覆盖到 unix 时间戳?
- zxing - 在 zxing 中不关闭摄像头
- mysql - Time() 函数返回 Null
- reactjs - 如何在 Jest 中测试 Javascript 的 toString()
- postgresql - 将 EBS 卷附加到新 EC2 实例后无法检索 PostgreSQL 数据库
- html - 悬停后顶部对齐图像
- mysql - 从 MySQL 表中获取记录时将结果设为 NULL
- julia - 我在编译时遇到错误,在添加和使用 julia 包时显示无法打开文件
- jquery - jquery在Angular中路由时找不到项目