【问题标题】:NoSuchMethodError when calling java code from scala从scala调用java代码时出现NoSuchMethodError
【发布时间】:2011-05-29 16:02:43
【问题描述】:

当我在 scala REPL 控制台中执行以下代码时:

java.util.Collections.max(new java.util.ArrayList[String]())

NoSuchMethodError 抛出异常:

java.lang.NoSuchMethodError: java.util.Collections.max(Ljava/util/Collection;)Lj
ava/lang/Comparable;
        at .<init>(<console>:8)
        at .<clinit>(<console>)
        at .<init>(<console>:11)
        at .<clinit>(<console>)
        at $export(<console>)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
        at java.lang.reflect.Method.invoke(Method.java:597)
        at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:592)

        at scala.tools.nsc.interpreter.IMain$Request$$anonfun$10.apply(IMain.sca
la:828)
        at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:4
3)
        at scala.tools.nsc.io.package$$anon$2.run(package.scala:31)
        at java.lang.Thread.run(Thread.java:662)

Scala 2.9.0.1、Java 1.6.0_25

为什么这里会抛出异常? 从 Java 执行的相同代码的行为符合预期(抛出 NoSuchElementException)。

【问题讨论】:

    标签: scala


    【解决方案1】:

    这是一个影响 Scala 2.8 和 2.9 的编译器错误,其中编译器不会计算正确的已擦除方法签名。我不知道有错误报告。

    编译方法:

    object Test { def main(a: Array[String]) {
      val a = new java.util.ArrayList[String]()
      java.util.Collections.max(a)
    }}
    

    结果转化为以下字节码:

    public void main(java.lang.String[]);
      Code:
       Stack=2, Locals=3, Args_size=2
       0:   new #16; //class java/util/ArrayList
       3:   dup
       4:   invokespecial   #18; //Method java/util/ArrayList."<init>":()V
       7:   astore_2
       8:   aload_2
       9:   invokestatic    #24; //Method java/util/Collections.max:(Ljava/util/Collection;)Ljava/lang/Comparable;
       12:  pop
       13:  return
    

    请注意,偏移量 9 处的字节码调用具有 Comparable 返回类型的静态方法,而实际的 Collections.max 具有 Object 作为返回类型:

    $ javap -p java.util.Collections | grep max
        public static java.lang.Object max(java.util.Collection);
    

    【讨论】:

    • 很好奇。 Javadoc 说 &lt;T extends Object &amp; Comparable&lt;? super T&gt;&gt; T.
    • @Daniel,JVM 查看方法的擦除类型;所以T 被擦除为Object,但Scalac 希望它被擦除为Comparable。您可以查看我的email in the scala-user mailing list 了解更多详情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 1970-01-01
    相关资源
    最近更新 更多