0

我试图得到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]orclassOf[Some]用于 Option 实例,这会getDeclaredMethod导致失败,因为 (?) 签名基于 Option 而不是 Some/None。

这是代码:

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参数的方法都失败了(否则一切正常)。

4

2 回答 2

1

回答: classOf[Option[_]]

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

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

于 2013-08-05T05:26:48.227 回答
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$
于 2013-08-05T07:11:04.603 回答