我必须编写自己的JDK动态代理来提供动态接口实现的能力。由于我使用akka
,因此必须使用Scala编写。但是我遇到了一些与Java不同的奇怪行为:
object Main extends App {
println(classOf[Message].getDeclaredMethod("msg")
.invoke(Message("Test"), null))
//throws IllegalArgumentException
}
case class Message(message: String){
def msg() = message
}
堆栈跟踪:
Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at Main$.delayedEndpoint$Main$1(Main.scala:2)
at Main$delayedInit$body.apply(Main.scala:1)
at scala.Function0$class.apply$mcV$sp(Function0.scala:34)
at scala.runtime.AbstractFunction0.apply$mcV$sp(AbstractFunction0.scala:12)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.App$$anonfun$main$1.apply(App.scala:76)
at scala.collection.immutable.List.foreach(List.scala:381)
at scala.collection.generic.TraversableForwarder$class.foreach(TraversableForwarder.scala:35)
at scala.App$class.main(App.scala:76)
at Main$.main(Main.scala:1)
at Main.main(Main.scala)
但我在Java中工作正常:
public static void main (String[] args) throws java.lang.Exception
{
System.out.println(Message.class.getDeclaredMethod("msg")
.invoke(new Message(), null)); //prints Message
}
public static class Message{
public String msg(){
return "Message";
}
}
为什么Scala会抛出异常?以及如何解决它?
答案 0 :(得分:3)
希望我能证明正在发生的事情:
class TheClass {
def theMethod:Unit = { println("It's me the method"); }
}
scala> classOf[TheClass].getDeclaredMethod("theMethod").invoke(new TheClass, null)
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
scala> classOf[TheClass].getDeclaredMethod("theMethod").invoke(new TheClass)
It's me the method
res1: Object = null
正如所料,但现在看看这个:
scala> classOf[TheClass]
.getDeclaredMethod("theMethod").invoke(new TheClass, Array.empty)
java.lang.IllegalArgumentException: wrong number of arguments
对此:
scala> classOf[TheClass]
.getDeclaredMethod("theMethod").invoke(new TheClass, Array.empty : _*)
It's me the method
res4: Object = null
请注意调用之间的区别:.invoke(new TheClass, Array.empty)
与.invoke(new TheClass, Array.empty : _*)
。会发生的事情是invoke
的第二个参数是 varargs ,当它被赋予普通Array.empty
或null
时,它应该变成一个数组。 scalac正在用Array(Array.empty)
和Array(null)
替换它们。当没有提供参数时,它实际上是Array.empty
,当我们使用: _*
时,它只是告诉编译器我们证明的参数是 varargs本身。