Scala如何获得所有继承trait的子对象

gcusky
  • 135
trait Base

object A extends Base // 正常,处理事件
object B extends Base // 正常,处理事件
object C extends Base // 正常,处理事件
class D extents Base // 异常

object Base {
  //TODO 验证继承 trait Base 的是否都是 object,不是则抛异常
  //TODO 分发从 akka actor 获取到的 event 到 Base 各自子对象中
}
  • 当使用 akka 抛出 Event 事件时,我希望通知所有继承了特质 Base 的对象ABC,它们各自再对事件进行各自的操作。
  • 现在想要的效果是 akka 抛出的事件由 Base 的伴生对象统一分发处理,同时验证继承 Base 的是否都是 object 单例。
回复
阅读 2.7k
1 个回答
✓ 已被采纳

这里需要用到反射机制:使用 Java 类库 reflections 里的 getSubTypesOf 获取所有子类,但想获得其对应的对象需要通过 getField 获得 MODULE$ 字段,根据该字段就可以获得对应的对象。

package com.gcusky.util.reflect

import org.reflections.Reflections
import scala.collection.JavaConverters._

object Base {
  def subObject[T](underlying: Class[T]): Seq[T] = {
    val reflects = new Reflections("com.gcusky.util.reflect")
    reflects.getSubTypesOf(underlying).asScala.map { sub =>
      sub.getField("MODULE$").get(null).asInstanceOf[T]
    }.toSeq
  }
}

因为在Scala中,单例对象和伴生对象编译完后会生成两个class文件:Base.classBase$.classBase$.class 类中有一个常量字段 MODULE$,它的类型就是当前类 Test$ 的类类型。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏