使用scala'查找对象;s运行时反射 上下文

使用scala'查找对象;s运行时反射 上下文,scala,reflection,Scala,Reflection,我目前使用scala 2.11.6,将来可能使用2.11.7。 给定类路径中已编译的类文件,我想做两件事: 查找实现特定接口的任何对象的名称: trait Service trait ServiceFactory { def create(): Service } ... package my.package object MyServiceFactory extends ServiceFactory { def create(): Service = new Service() }

我目前使用scala 2.11.6,将来可能使用2.11.7。 给定类路径中已编译的类文件,我想做两件事:

  • 查找实现特定接口的任何对象的名称:

    trait Service
    trait ServiceFactory {
      def create(): Service
    }
    ...
    package my.package
    object MyServiceFactory extends ServiceFactory {
      def create(): Service = new Service()
    }
    
    这里的名称类似于
    my.package.MyServiceFactory
    ,因为它实现了
    ServiceFactory
    特性

  • 给定对象的完全限定名,我希望获得对对象实例的引用

    val factory = getInstance[ServiceFactory]("my.package.MyServiceFactory")
    val service = factory.create()
    
问题 两种方案的问题都是验证类型继承并确保它是单例对象。 检查课程似乎很简单,但给出了所有 我可以理解,没有人帮我实现类似于
isSingletonObject(名称:String):Boolean的东西,如在:

import scala.reflect.runtime.{universe => ru}
val rm = ru.runtimeMirror(classLoader)

def getInstance[T](name: String)(implicit tt: ru.TypeTag[T]): T = {
  if (!isSingletonObject(name)) throw new RuntimeException(
    s"$name does not specify a singleton object")
  val moduleSym = try rm.staticModule(name).asModule
  if (!(moduleSym.moduleClass.asClass.selfType <:< tt.tpe))
      throw new RuntimeException("Type of loaded module " + moduleSym.fullName
        + " does not satisfy subtype relationship with "
        + tt.tpe.typeSymbol.fullName)
  val mm = rm.reflectModule(moduleSym.asModule)
  mm.instance.asInstanceOf[T]
}
import scala.reflect.runtime.{universe=>ru}
val rm=ru.runtimeMirror(类加载器)
def getInstance[T](名称:字符串)(隐式tt:ru.TypeTag[T]):T={
如果(!isSingletonObject(name))引发新的RuntimeException(
s“$name不指定单例对象”)
val moduleSym=尝试rm.staticModule(名称).asModule

如果(!(moduleSym.moduleClass.asClass.selfType)用于第一个问题,您可以使用。注意,它会找到Java类,与
对象
s对应的类的名称将以
$class
结尾。另请参见


对于第二个,Scala反射中的
对象
s,因此您不需要
isSingletonObject(name)
;如果不需要,代码中的
rm.staticModule(name).asModule
将失败。似乎没有办法检查它是否是编译器生成的空伴生对象(
isSynthetic
返回false),但它们无论如何都会被子类型检查排除在外(Java类的静态部分也是如此,但您也可以使用
isJava
过滤掉它们).

所以您建议只进行反射并检查是否存在异常?对于第二个问题,是的。请参阅第一个问题的编辑答案。谢谢。我找到了一个类似的库,并使用它来获取名称列表。关于对象,似乎没有正确的方法来确保它是scala对象,可能是因为jvm对scala?a没有特殊支持nyway我扫描所有具有该特性的类,并且只使用模块。使用
myservicecfactory
myservicecfactory$
这两个类在使用scala反映时似乎都引用相同的对象实例,这也没有什么区别。“似乎没有合适的方法来确保它是scala对象,可能是因为jvm没有对scala的特殊支持。”正如回答中提到的,符号有一个
isJava
方法。