我如何获得Scala的Option类,以便将其传递给getDeclaredMethod()

时间:2013-08-05 05:22:36

标签: scala generics

我正在尝试获取classOf[the-abstract-class-Option],但我总是得到classOf[the-Option-*object*]。我怎样才能获得抽象类的类

Option.getClassclassOf[Option[_]]都给了我class scala.Option$

编辑:我不需要问这个;突然之间,classOf[Option[_]]工作正常,很奇怪。的 /修改

背景

我试图通过反射调用一个带Option[String]参数的方法 它的签名如下:...(..., anySectionId: Option[String], ...)...
在我调用该方法之前,我通过getDeclaredMethod进行查找。但要做到这一点,我需要一个参数类型列表,我通过在我将要给该方法的每个参数上调用_.getClass来构造。但是_.getClass会为选项实例返回classOf[None]classOf[Some],这会导致getDeclaredMethod失败,因为(?)签名基于选项而不是某些/无。

以下是代码:

val clazz: Class[_] = Play.current.classloader.loadClass(className)

val paramTypes = arguments.map(_ match {
  case None => Option.getClass  // gives me the object, not the abstract class
  case _: Some[_] => classOf[Option[_]]  // this also gives me the object  :-(
  case x => x.getClass  // results in None or Some for Option instances
})

val m: jl.reflect.Method = clazz.getDeclaredMethod("apply", paramTypes: _*)

并且上面的最后一行对于具有任何Option参数的方法失败(否则一切正常)。

2 个答案:

答案 0 :(得分:1)

答案:classOf[Option[_]]

奇怪!突然classOf[Option[_]]起作用了。在我提交问题之前,我确信我测试了一两次:-(也许IDE在我重新编译之前没有时间保存文件,很奇怪。

我不知道是否应该删除这个问题。或许我应该保持原样,以防classOf[Option[_]]对每个人都不明显。

答案 1 :(得分:1)

最好的方法是使用Scala反射。

下一个最好的方法是不要通过尝试匹配参数类型来为自己工作。

使用getClass对于子类型失败:

scala> class Foo
defined class Foo

scala> class Bar extends Foo
defined class Bar

scala> class Baz { def baz(f: Foo) = 1 }
defined class Baz

scala> val b = new Baz
b: Baz = Baz@d33eaa9

scala> val p = new Bar
p: Bar = Bar@406c5ca2

scala> classOf[Baz].getDeclaredMethod("baz", p.getClass)
java.lang.NoSuchMethodException: Baz.baz(Bar)

只需匹配名称即可:

scala> classOf[Baz].getMethods.find(_.getName == "baz") map (_.invoke(b,p)) getOrElse -1
res5: Any = 1

或过滤掉穷人超载分辨率的参数数量,然后可以过滤所有符合类型的参数。

意外获取物体的符号实际上是:

scala> classOf[Option$]
res8: Class[Option$] = class scala.Option$