views:

179

answers:

2

I have 2 simple methods in a scala library class:

class Foo {
  def bar(args : String*) : Unit = println("Foo.bar with: " + args)
  def bar(args : Array[String]) : Unit = bar(args.toSeq : _*)
}

This all compiles nicely. I then put this in a library foo.jar and try and compile the following piece of Java:

import Foo
public class Test {

    public static void main(String[] args) {
        Foo foo = new Foo();
        foo.bar("Hello", "World"); //DOES NOT COMPILE
    }
}

I can replace the offending line with:

foo.bar(new String[] { "Hello", "World" }); //OK

But this seems to defeat the point. How can I call it from Java using Java varargs-like syntax?

+1  A: 

Not entierly certain but I think varargs in Scala uses Sequences and are different from the java implementation. I think the easiest way to accomplish what you want is to subclass the Foo scala class in Java and add a bar method that takes a Java vararg i.e.

public class JavaFoo extends Foo {
    public void bar(String... args) {
         super.bar(args)
    }
}

The JavaFoo vararg method can then be called using vararg syntax in Java.

Hope it helps :)

Emil H
Hmmm... tried Daniel's suggestion, but I could not get that to work using scala 2.8 beta. Is the compilation to both a java vararg and a scala vararg something that has just been added recently? Decompiling the bytecode just yields a Foo class with a public void bar(Seq<String> args) method...
Emil H
+2  A: 

In 2.8 (dunno about 2.7), if you override a varargs method from a Java parent, or implement a varargs method from a Java interface, then the Scala compiler will generate two methods, one for Scala, one for Java. The Java one -- as you can see for yourself by inspecting the bytecode — simply takes the varargs array and wraps it, then passed the WrappedArray to the Scala version that's expecting a Seq.

If there is a way to force the compiler to generate the forwarder under other circumstances, I don't know about it. I doubt it exists. Seems like providing a way to ask for it (an annotation, I guess) would be a reasonable enhancement request.

Seth Tisue