Scala offre @varargs
annotation che genera un metodo di inoltro Java varargs, che permette di scrivere qualcosa del genere:astratti metodi e l'annotazione varargs
import scala.annotation.varargs
class Foo {
@varargs def foo(args: String*): Unit = {
args.foreach(println)
}
}
E poi chiamare questo metodo da Java senza la necessità di creare un scala.Seq
:
Foo foo = new Foo();
foo.foo("a", "b");
che è piuttosto bello.
Purtroppo la parte di inoltro non sembra accadere quando il metodo è astratto:
trait Bar {
@varargs def bar(args: String*): Unit
}
class Baz extends Bar {
def bar(args: String*): Unit = {
args.foreach(println)
}
}
Ora, se abbiamo questo codice Java:
Bar bar = new Baz();
bar.bar("a", "b");
Otteniamo questa eccezione (in fase di esecuzione) :
java.lang.AbstractMethodError: Baz.bar([Ljava/lang/String;)V
possiamo confermare il problema con 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();
}
Quindi, lo spedizioniere sicuramente non viene implementato.
Mettere l'annotazione su entrambi bar
metodi fallisce la compilazione:
A method with a varargs annotation produces a forwarder method with the same
signature (args: Array[String])Unit as an existing method.
E naturalmente mettere l'annotazione solo sul bar
in Baz
significa che non possiamo usare solleva da un'istanza Bar
.
Sembra che debba essere un bug, ma sembra anche estremamente facile da eseguire, e non vedo nulla nel tracker del problema. Sto usando correttamente @varargs
? Se è così, c'è una soluzione che farebbe fare ciò che ti aspetteresti qui?
Ops. Mi sembra un altro bug.Grazie a una soluzione "jugaad" per l'interoperabilità. Perbacco! quanti altri stanno mentendo lì? – Jatin
Sembra un insetto. Prova a inviare un nuovo bug al tracker dei problemi. – Luminous