加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scala反射 – 根据特征加载或查找类

发布时间:2020-12-16 08:49:03 所属栏目:安全 来源:网络整理
导读:scala反射API(2.10)是否提供了更简单的方法来搜索加载的类并将列表过滤到实现已定义特征的特定类? 即; trait Widget { def turn(): Int}class Cog extends Widget { def turn() = { 5 }}class Sprocket extends Widget { def turn() = { 10 }} 我想在类库中
scala反射API(2.10)是否提供了更简单的方法来搜索加载的类并将列表过滤到实现已定义特征的特定类?
即;

trait Widget {
  def turn(): Int
}

class Cog extends Widget {
  def turn() = {
    5
  }
}

class Sprocket extends Widget {
  def turn() = {
   10
  }
}

我想在类库中搜索扩展Widget并实例化这些类的任何内容.所以我最终会得到一个Cog和Sprocket的例子.

我在Java中完成了类似的迭代,通过类目录,形成类名并使用Class.forName加载一个Class对象然后检查.我只是想知道scala反射API是否提供了更简单的搜索方式.到目前为止我看到的所有示例总是从已知的类实例化开始,而不是从搜索可用类开始.

解决方法

这就是ServiceLoader的用途.

我认为反射API确实可以更容易地理清你需要的东西(即,用于过滤而不是用于查询类加载器).

如果,通过您的短语“搜索已加载的类”,您实际上是指已经加载的类,请参阅this question以获取它们.

你可以想象一个带有初始化程序的小部件库,它只是确保加载它所知道的所有小部件类.然后客户端只需要知道初始化器.

型式试验是一样的.

val need = typeOf[Whatsit[Cog]]
for (x <- (ServiceLoader load classOf[Whatsit[_]]).asScala) { 
  val im = currentMirror reflect x 
  if (im.symbol.toType weak_<:< need)
    Console println s"$x is what I need"
  else
    Console println s"$x is not what I need,I'm looking for a $need"
}

你在哪里寻找带有类型参数的东西:

trait Whatsit[+A <: Widget] {
  def widget: A
}

class Engine extends Whatsit[Cog] {
  def widget = new Cog
}

class FlyWheel extends Whatsit[Sprocket] {
  def widget = new Sprocket
}

样品:

widgets.Engine@f9da0cd is what I need
widgets.FlyWheel@4cfdbb9f is not what I need,I'm looking for a widgets.Whatsit[widgets.Cog]

如果您使用ServiceLoader已经十年了,并且不需要复习:

apm@mara:~/tmp$ls -R META-INF
META-INF:
MANIFEST.MF  services

META-INF/services:
widgets.Whatsit  widgets.Widget
apm@mara:~/tmp$cat META-INF/services/widgets.Widget
widgets.Cog
widgets.Sprocket
apm@mara:~/tmp$cat META-INF/services/widgets.Whatsit 
widgets.Engine
widgets.FlyWheel

东西:

package widgets

trait Widget {
  def turn(): Int
  override def toString = s"Widget ${getClass.getSimpleName}"
}

class Cog extends Widget {
  def turn() = 5
}

class Sprocket extends Widget {
  def turn() = 10
}

trait Whatsit[+A <: Widget] {
  def widget: A
  override def toString = s"Whatsit ${getClass.getSimpleName} of $widget"
}

class Engine extends Whatsit[Cog] {
  def widget = new Cog
}

class FlyWheel extends Whatsit[Sprocket] {
  def widget = new Sprocket
}

比较Scala和Java.我想了解一下有多少LOC来获取GenericInterfaces并在Scala中找到你想要的东西,但后来我结束了这个练习.

package findwidgets

import reflect._
import reflect.runtime.universe._
import reflect.runtime.currentMirror
import scala.collection.JavaConverters._
import java.util.ServiceLoader

object Test extends App {
  import widgets.{ Widget,Whatsit,Cog }
  val ws = (ServiceLoader load classOf[Widget]).asScala
  for (w <- ws) {
    Console println s"Turn a ${w.getClass} by ${w.turn}"
  }
  val need = typeOf[Whatsit[Cog]]
  for (x <- (ServiceLoader load classOf[Whatsit[Cog]]).asScala) {
    val im = currentMirror reflect x
    if (im.symbol.toType weak_<:< need)
      Console println s"$x is what I need"
    else
      Console println s"$x is not what I need,I'm looking for a $need"
    // java says:
    if (classOf[Whatsit[Cog]] isAssignableFrom x.getClass)
      Console println s"Um,OK,I'll take the $x"
    else
      Console println s"${classOf[Whatsit[Cog]]} isn't ass'able from ${x.getClass}"
  }
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读