Question: Question:
I'm trying to use the overloaded methods provided by the Java library in Scala.
class X{
public <E> void f(E... values){ System.out.println(1); }
public void f(Object value){ System.out.println(2); }
}
However, in Scala, if the parameter types are compatible, you will not be able to resolve which of the overloaded methods you should use and you will get a compile error.
val x = new X()
x.f("foo")
error: ambiguous reference to overloaded definition,
both method f in class X of type (value: Any)Unit
and method f in class X of type [E](values: E*)Unit
match argument types (String)
Even if the parameter part at the time of calling is "foo":Object
or "foo".asInstanceOf[Object]
, the situation does not change. You can use reflection as a workaround.
classOf[X].getMethod("f", classOf[Object]).invoke(x, "foo") // => 2
Fundamentally, how do you explicitly call the method on the 2. side in Scala?
Java 11.0.2 / Scala 2.12.8
Answer: Answer:
Probably, you can't call the setDefault(Object value)
method from Scala.
In dotty (Scala 3.x), it may be possible in some way (?).
https://github.com/lampepfl/dotty/issues/5792
For the time being, there are three possible compromises.
(The method of calling by reflection is described in the question text, so I excluded it)
Compromise 1: Consider using other libraries
- https://stackoverflow.com/questions/2315912/best-way-to-parse-command-line-parameters
- https://stackoverflow.com/questions/8112879/scala-command-line-parser-with-subcommand-support
Compromise 2: Call the setDefault(E... value)
method
With this method, I feel that I can call it with the following code.
arg.setDefault(Seq("foo"): _*)
However, I think that the default value displayed in the help will be as follows.
(Extra []
is attached)
(default: [foo])
Compromise 3: Write a helper class in Java and use it in Scala
This is the method used by mdekstrand / argparse4s , which is a Scala wrapper for argparse4j, but under src/main/java
.
public static void setDefault(Argument arg, Object dft)
Define a helper class with a method called, and use this Java class from Scala.
/src/main/java/net/elehack/argparse4s/ArgConfig.java
package net.elehack.argparse4s;
import net.sourceforge.argparse4j.inf.Argument;
class ArgConfig {
public static void setDefault(Argument arg, Object dft) {
arg.setDefault(dft);
}
}
* This Scala wrapper library itself does not seem to be maintained as of 2019.