Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use Scala varargs from Java code

There are plenty of articles on calling Java varargs from Scala code, but the only thing I could find the opposite way round was this question: Using scala vararg methods in java, which doesn't have any concrete examples.

I'm trying to use scala.Console from some Java code, for the reason that java.io.Console doesn't work in Eclipse, whereas the Scala one does. But I cannot get the method

def readLine (text: String, args: Any*): String

to work because it seems to be expecting a scala.collection.Seq[Any] for the second argument, and I don't see how to create a Seq in Java. How can I work around this?

Things I've tried:

1) Using null

// Java
String s = scala.Console.readLine("Enter text: ", null);

- get rewarded with a NullPointerException.

2) Replacing the null with scala.collection.Seq.empty(), but javac reports all sorts of errors such as Seq not having an empty method.

3) Using the Nil object in the scala.collection.immutable package object, but the syntax suggested here, which would be scala.collection.immutable.package$Nil$.MODULE$, but that can't be resolved.

Of course I could just use the readLine() method that doesn't take varargs, but that would be too easy.

like image 608
Luigi Plinge Avatar asked Apr 08 '12 04:04

Luigi Plinge


People also ask

How do you handle varargs in Java?

Important Points regarding Varargs Before JDK 5, variable length arguments could be handled in two ways: One was using overloading, other was using array argument. There can be only one variable argument in a method. Variable argument (Varargs) must be the last argument.

Is it good to use varargs in Java?

Varargs are useful for any method that needs to deal with an indeterminate number of objects. One good example is String. format . The format string can accept any number of parameters, so you need a mechanism to pass in any number of objects.

What is Varargs in Scala?

Scala varargs: The concept of providing variable-length argument to a method.

Can Varargs be null Java?

As Java cannot determine the type of literal null , you must explicitly inform the type of the literal null to Java. Failing to do so will result in an NullPointerException . For example, the following main method invokes the foo method with literal null .


Video Answer


1 Answers

You can use:

scala.collection.Seq$.MODULE$.empty();

from Java code to create an empty sequence. Otherwise, you can use:

new scala.collection.mutable.ArrayBuffer();

to create an empty array buffer into which you can then add elements and use it as an argument to Scala vararg methods.

Otherwise, if you design a Scala library with vararg methods which you want to use from Java code, then use the varargs annotation. It will generate a Java version of the method which takes an array instead of a Seq.

scala> class A {
     |   @annotation.varargs def foo(x: Int*) { println(x) }
     | }
defined class A

scala> println(classOf[A].getMethods.toList)
List(public void $line1.$read$$iw$$iw$A.foo(scala.collection.Seq), public void $line1.$read$$iw$$iw$A.foo(int[]), ...)

Above, reflection shows that there are 2 versions of method foo generated - one that takes a Seq[Int] and another which takes an int[].

like image 86
axel22 Avatar answered Oct 07 '22 19:10

axel22