我正在尝试获取classOf[the-abstract-class-Option]
,但我总是得到classOf[the-Option-*object*]
。我怎样才能获得抽象类的类?
Option.getClass
和classOf[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
参数的方法失败(否则一切正常)。
答案 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$