【发布时间】:2012-07-23 08:02:53
【问题描述】:
我期待这段代码(在精炼类型上使用模式匹配后调用匿名类的方法)
(new {
def foo : Unit = println("Called foo method")
} : Any) match {
case f : {def foo : Unit} ⇒
println("Has foo method")
f.foo
}
打印
Has foo method
Called foo method
(以及未经检查的警告)。
我知道由于类型擦除,匹配总是成功,但这不应该导致问题,因为f 的运行时类型(即使考虑擦除)应该是$anon$NameOfSomeAnonymousClassThatHasAfooMethod
当进入 Scala REPL (2.9.1) 时,它实际上会抛出 NoSuchMethodException:
<console>:11: warning: refinement AnyRef{def foo: Unit} in type pattern AnyRef{def foo: Unit} is unchecked since it is eliminated by erasure
case f : {def foo : Unit} ⇒
^
Has foo method
java.lang.NoSuchMethodException: $anon$1.foo()
at java.lang.Class.getMethod(Class.java:1622)
at .reflMethod$Method1(<console>:13)
at .<init>(<console>:13)
at .<clinit>(<console>:13)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Thread.java:679)
为什么?
编辑
事实证明,最直接的原因是foo 是作为私有生成的。我在回答中推测了造成这种情况的原因,但我不确定。如果您有任何想法,请随时将其发布为答案!
【问题讨论】:
-
stackoverflow.com/questions/3200301/… 不是原因,因为这里
foo是公开的。 -
你确定这是修改后的名字吗?我会打印所有的
getMethods来检查。 -
不完全受欢迎的建议,我知道,但我会避开结构类型:-s
-
@PeterLawrey:如果我使用
f.getClass.getMethods foreach println,它只会列出Object方法。但是为什么它给出了错误的课程呢?
标签: java scala reflection jvm anonymous-class