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得当吗?如果是这样,是否有一种解决方法可以使它达到您期望的效果?
我不知道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同样的方式愚弄,也许你就能克服这个错误。
| 归档时间: |
|
| 查看次数: |
838 次 |
| 最近记录: |