Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I implement a Java interface with variadic methods in Scala?

I am implementing a Java interface containing variadic methods like so:

interface Footastic { 
  void foo(Foo... args);
}

Is it possible to implement this interface in Scala? Variadic functions are handled differently in Scala, so the following won't work:

class Awesome extends Footastic {
  def foo(args: Foo*): Unit = { println("WIN"); }
  // also no good: def foo(args: Array[Foo]): Unit = ...
}

Is this even possible?

like image 832
pchiusano Avatar asked Sep 23 '11 18:09

pchiusano


People also ask

Can Java and Scala work together?

Is it possible to mix Scala and Java code? Yes, there is the ability to mix both types of code. It is possible to create an SBT project, put Scala code in src/main/scala and java code in src/main/java in the same project and make it work.

How do you call a method in Scala in Java?

scala> var a = Array(1, 2, 3) a: Array[Int] = Array(1, 2, 3) scala> :javap -c a public class $line3. $read$$iw$$iw$ { ... public int[] a(); ... As you can see, the above Array[Int] has been convert to int[] primitive type arrays. so for this reason, this maybe cause incompatible for Java method.

Can we use Java libraries in Scala?

Scala is designed to work smoothly with Java and Java libraries like JMSL. This is clearly evident in how Scala picks up the same CLASSPATH environment variable Java uses, so if the Java library you wish to use is already there in the CLASSPATH, then you're good to go.


1 Answers

The code you've written works as-is.

The scala compiler will generate a bridge method which implements the signature as seen from Java and forwards to the Scala implementation.

Here's the result of running javap -c on your class Awesome exactly as you wrote it,

public class Awesome implements Footastic,scala.ScalaObject {
  public void foo(scala.collection.Seq<Foo>);
    Code:
       0: getstatic     #11                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
       3: ldc           #14                 // String WIN
       5: invokevirtual #18                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
       8: return

  public void foo(Foo[]);
    Code:
       0: aload_0
       1: getstatic     #11                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
       4: aload_1
       5: checkcast     #28                 // class "[Ljava/lang/Object;"
       8: invokevirtual #32                 // Method scala/Predef$.wrapRefArray:([Ljava/lang/Object;)Lscala/collection/mutable/WrappedArray;
      11: invokevirtual #36                 // Method foo:(Lscala/collection/Seq;)V
      14: return

  public Awesome();
    Code:
       0: aload_0
       1: invokespecial #43                 // Method java/lang/Object."<init>":()V
       4: return
}

The first foo method with with Seq<Foo> argument corresponds to the Scala varargs method in Awesome. The second foo method with the Foo[] argument is the bridge method supplied by the Scala compiler.

like image 79
Miles Sabin Avatar answered Sep 19 '22 14:09

Miles Sabin