Assume there is a base class in a Java library which cannot be modified
public class BaseClass {
public Something function(int... args){ ... }
}
Typically, this would be overridden in Scala by using the Scala varargs syntax:
class TypicalScalaVarargsOverrideClass extends BaseClass {
override def function(args: Int*): Something = { ... }
}
But if TypicalScalaVarargsOverrideClass.function is invoked in Java code, a no suitable method error is raised:
// no args
no suitable method found for function(no arguments)
method TypicalScalaVarargsOverrideClass.function(scala.collection.Seq<java.lang.Object>) is not applicable
(actual and formal argument lists differ in length)
method TypicalScalaVarargsOverrideClass.function(int[]) is not applicable
(actual and formal argument lists differ in length)
// 1 arg
no suitable method found for function(int)
method TypicalScalaVarargsOverrideClass.function(scala.collection.Seq<java.lang.Object>) is not applicable
(argument mismatch; int cannot be converted to scala.collection.Seq<java.lang.Object>)
method TypicalScalaVarargsOverrideClass.function(int[]) is not applicable
(argument mismatch; int cannot be converted to int[])
// 3 args
no suitable method found for function(int,int,int)
method TypicalScalaVarargsOverrideClass.function(scala.collection.Seq<java.lang.Object>) is not applicable
(actual and formal argument lists differ in length)
method TypicalScalaVarargsOverrideClass.function(int[]) is not applicable
(actual and formal argument lists differ in length)
Typically, the solution to this is to add @varargs annotation, making the bytecode generated from the Scala code compatible the Java:
class UsingVarargsAnnotationClass extends BaseClass {
@varargs
override def function(args: Int*): Something = { ... }
}
But this results in a double definition error, as it now collides with the original function definition:
double definition:
override def function(args: Int*): Something at line 1 and
override def function(args: Array[Int]): Something at line 3
have same type after erasure: (args: Array[Int])Something
override def function(args: Int*): Something = {
So is there a way, in Scala (specifically 2.12 or 2.13), to define an override of a Java varargs method which is still callable from both Scala and Java?
The primary suggestion I've received is to avoid this entirely by defining the interface of the override class in Java, with the override methods making a call to some delegate function defined in Scala (there are a few ways to do that).
override def function(args: Array[Int])in Scala work?