使用反射获取所有在 Scala 中实现特征的类 [英] Get all the classes that implements a trait in Scala using reflection

查看:33
本文介绍了使用反射获取所有在 Scala 中实现特征的类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想列出实现特定特征的所有案例类.我目前正在使用 Clapper ClassUtil 来做这件事.我能够获得直接实现特征的案例类.但是,我无法获得未直接实现该特征的其他类.如何获得所有直接或间接实现特征的类.?

I want to list out all the case classes which implements a particular trait. I am currently using Clapper ClassUtil for doing that. I am able to get the case classes that are directly implementing a trait. However, I am not able to get the other classes which are not directly implementing the trait. How can I get all classes which directly or indirectly implements a trait. ?

val finder = ClassFinder()
finder.getClasses().filter(_.isConcrete).filter(_.implements("com.myapp.MyTrait"))

Scala 版本:2.11

Clapper 类实用程序版本:1.0.6

Clapper Class Util Version : 1.0.6

还有其他方法可以获得这些信息吗?有人可以指出我正确的方向吗?我尝试使用 scala.reflect 但无法理解如何获取信息.

Is there any other way I can get these information? Can someone point me to the right direction? I tried using scala.reflect but could not understand how to get the info.

EDIT:

示例特征和用法:

trait BaseEntity
trait NamedEntity{ val name:String}
trait MasterDataEntity extends NamedEntity

case class Department(id:Long, override val name:String) extends MasterDataEntity
case class Employee(id:Long, name:String) extends BaseEntity
case class User(id:Long, override val name:String) extends NamedEntity

现在,如果我将特征指定为 NamedEntity,我应该能够同时获得 DepartmentUser,因为它们都是直接或间接实现 NamedEntity.使用 implements 方法,它只会给用户.我也尝试过使用 interfaces 方法,该方法也将仅提供直接超类.

Now, if I give the trait as NamedEntity, I should be able to get both Department and User since they both are directly or indirectly implementing NamedEntity. With implements method, it will give only User. I also tried by using interfaces method, which will also provide the direct super classes only.

推荐答案

源代码,问题似乎是它不遵循接口层次结构.如果你这样做,你会发现所有实例:

Looking at the source code, the problem seems to be that it doesn't follow the interfaces hierarchy. If you do that, you find all instances:

package foo

import java.io.File

import org.clapper.classutil.{ClassFinder, ClassInfo}

object Main extends App {
  val jar     = new File("target/scala-2.11/class_test_2.11-0.1.0.jar")
  val finder  = ClassFinder(jar :: Nil)
  val classes = ClassFinder.classInfoMap(finder.getClasses().iterator)
  val impl    = find("foo.NamedEntity", classes)
  impl.foreach(println)

  def find(ancestor: String, classes: Map[String, ClassInfo]): List[ClassInfo] =
    classes.get(ancestor).fold(List.empty[ClassInfo]) { ancestorInfo =>
      val ancestorName = ancestorInfo.name

      def compare(info: ClassInfo): Boolean =
        info.name == ancestorName ||
        (info.superClassName :: info.interfaces).exists {
          n => classes.get(n).exists(compare)
        }

      val it = classes.valuesIterator
      it.filter { info => info.isConcrete && compare(info) } .toList
    }
}

这篇关于使用反射获取所有在 Scala 中实现特征的类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆