微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

从反射的Java类实例中获取ClassTag

是否可以从通过反射获得的Java类实例获取classtag信息?

这是情况.我有一个Scala案例类,如下所示:

case class Relation[M : classtag](id: UUID, 
                                  model: Option[M] = None)

它是这样使用的(虽然有更多的类相互关联):

case class Organization(name: String)

case class Person(firstName: String, 
                  lastName: String,
                  organization: Relation[Organization])

我想要做的是以编程方式使用如下所示的东西构建这些关系的树:

private def generateFieldMap(clazz: Class[_]): Map[String, Class[_]] = {
    clazz.getDeclaredFields.foldLeft(Map.empty[String, Class[_]])((map, field) => {
        map + (field.getName -> field.getType)
    })
}

private def getRelationModelClass[M : classtag](relationClass: Class[_ <: Relation[M]]): Class[_] = {
    classtag[M].runtimeClass
}

def treeOf[M: classtag](relations: List[String]): Map[String, Any] = {
    val normalizedRelations = ModelHelper.normalize(relations)
    val initialFieldMap = Map("" -> generateFieldMap(classtag[M].runtimeClass))
    val relationFieldMap = relations.foldLeft(initialFieldMap)((map, relation) => {
        val parts = relation.split('.')
        val parentRelation = parts.dropRight(1).mkString(".")
        val relationClass = map(parentRelation)(parts.last)
        val relationModelClass = relationClass match {
            case clazz: Class[_ <: Relation[_]] => getRelationModelClass(clazz)
            case _ => throw ProcessstreetException("cannot follow non-relation: " + relation)
        }
        val fieldMap = generateFieldMap(relationModelClass)
        map + (relation -> fieldMap)
    })
    relationFieldMap
}

val relations = List("organization")
val tree = treeOf[Person](relations)

这不会编译.我收到此错误

[error] Foo.scala:148: not found: type _$12
[error]                 case clazz: Class[_ <: Relation[_]] => getRelationModelClass(clazz)
[error]                                   ^
[error] one error found
[error] (compile:compile) Compilation Failed

基本上,我想要做的就是能够访问classtag信息,因为我拥有的只是java类.这可能吗?

解决方法:

是的,绝对可能也很容易:

val clazz = classOf[String]
val ct = classtag(clazz)  // just use classtag.apply() method

在您的示例中,您需要调用getRelationModelClass方法,如下所示:

getRelationModelClass(clazz)(classtag(clazz))

这是可能的,因为[T:classtag]语法隐式地创建了第二个参数列表,如(implicit ct:classtag [T]).通常它由编译器填充,但没有任何东西阻止您显式使用它.

您也不需要同时将此clazz的类AND类标记传递给该方法.你甚至没有在它的体内使用显式的类对象.只需传递类标签,就足够了.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐