我试图创建一个扩展特定类的所有对象的地图。我想在以任何其他方式使用对象之前访问此列表。我试过这段代码:
import scala.collection.mutable
abstract class Registered(tag:String) {
Registered.registry(getClass.getName) = tag
val x = 1
}
object Registered {
val registry = mutable.Map[String, String]()
}
object objA extends Registered("foo")
object objB extends Registered("bar")
object TheMain {
def main(args:Array[String]) {
listem
touchem
listem
}
def listem = {
println(s"listing ${Registered.registry.size} entries:")
for ((k,v) <- Registered.registry) yield println(s"$k: $v")
}
def touchem = {
val x = objA.x + objB.x
}
}
输出:
listing 0 entries:
listing 2 entries:
objB$: bar
objA$: foo
我需要第一行才能列出2个条目。我知道这不起作用,因为地图总是空的:对象初始化是懒惰的,所以在以某种方式引用它之前我不能引用它。
创建此类注册表的好方法是什么?可以(应该)我以某种方式使用反射吗?
答案 0 :(得分:0)
这更能解释你在评论中添加的内容而不是原始问题:“在我的情况下,我想查看给定类型的所有对象,并使用具有特定标记的对象。来自命令行参数。“
为什么不在这种情况下动态创建对象?像这样,也许:
class Registered(tag:String)
object Registered {
val registry = mutable.Map[String,String]
def apply(tag: String) = registered.getOrElseUpdate(tag, new Registered(tag))
}
或者,你坚持使用静态创建的实例,你可以这样做(甚至不需要注册表):
sealed class Registered(tag:String)
object objA extends Registered("foo")
object objB extends Registered("bar")
object Registered {
def apply(tag: String) = tag match {
case "foo" => objA
case "bar" => objB
case _ => throw new InvalidArgumentException("Unknown tag: %s".format(x))
}
}
答案 1 :(得分:0)
看看Reflections library。您应该可以执行以下操作来查找从some.package.name
继承的Thingy
中的所有类:
def getThingies(): Set[Class[_ <: Thingy]] = {
val reflections = new Reflections("some.package.name");
reflections.getSubTypesOf(classOf[Thingy]);
}
当然,您可以指定classOf[Object]
来获取包中的所有类。您还可以搜索具有特定注释的包。