java – How to explicitly resolve overloaded method ambiguity in Scala?

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

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.

Scroll to Top