抽象方法和varargs注释

Tra*_*own 13 java scala variadic-functions scala-java-interop

Scala提供了一个生成Java varargs转发器方法的@varargs注释,可以编写如下内容:

import scala.annotation.varargs

class Foo {
  @varargs def foo(args: String*): Unit = {
    args.foreach(println)
  }
}
Run Code Online (Sandbox Code Playgroud)

然后从Java调用此方法而无需创建scala.Seq:

Foo foo = new Foo();
foo.foo("a", "b");
Run Code Online (Sandbox Code Playgroud)

这很不错.

不幸的是,当方法是抽象的时,似乎没有发生转发部分:

trait Bar {
  @varargs def bar(args: String*): Unit
}

class Baz extends Bar {
  def bar(args: String*): Unit = {
    args.foreach(println)
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我们有这个Java代码:

Bar bar = new Baz();
bar.bar("a", "b");
Run Code Online (Sandbox Code Playgroud)

我们得到这个异常(在运行时):

java.lang.AbstractMethodError: Baz.bar([Ljava/lang/String;)V
Run Code Online (Sandbox Code Playgroud)

我们可以用以下方法确认问题javap:

public interface Bar {
  public abstract void bar(java.lang.String...);
  public abstract void bar(scala.collection.Seq<java.lang.String>);
}

public class Baz implements Bar {
  public void bar(scala.collection.Seq<java.lang.String>);
  public Baz();
}
Run Code Online (Sandbox Code Playgroud)

所以不行,货运代理肯定没有得到实施.

在两个bar方法上放置注释都无法编译:

A method with a varargs annotation produces a forwarder method with the same
signature (args: Array[String])Unit as an existing method.
Run Code Online (Sandbox Code Playgroud)

当然,只将注释放在barin中Baz意味着我们不能使用Bar实例中的转发器.

这似乎是一个bug,但它似乎也很容易碰到,我在问题跟踪器中没有看到任何东西.我使用@varargs得当吗?如果是这样,是否有一种解决方法可以使它达到您期望的效果?

Suz*_*ioc 2

我不知道Scala,但在 Java 中 varargs 只是一个数组。

所以在 Java 中它会以这种方式工作,但有一个警告:

package tests.StackOverflow.q27052394;

import java.util.Arrays;

public class Runner {

    public interface Bar {
      public abstract void bar(java.lang.String ... ss);
    }

    public static class Baz implements Bar {
      public void bar(java.lang.String[] array) {
          System.out.println(Arrays.toString(array));
      }
    }

    public static void main(String[] args) {

        Bar b = new Baz();

        b.bar("hello", "world");

    }

}
Run Code Online (Sandbox Code Playgroud)

如果你能以Scala同样的方式愚弄,也许你就能克服这个错误。