Vic
Vic

Reputation: 109

Java method call is ambiguous

there are 2 methods:

public static TermsQueryBuilder termsQuery(String name, int... values) {
    return new TermsQueryBuilder(name, values);
}
public static TermsQueryBuilder termsQuery(String name, Object... values) {
    return new TermsQueryBuilder(name, values);
}

when i called

termsQuery("operatorType", 1);

it says that is ambiguous.

Please Help ...

all the methods are in Elasticsearch,for example:

public static TermsQueryBuilder termsQuery(String name, String... values) {
    return new TermsQueryBuilder(name, values);
}
public static TermsQueryBuilder termsQuery(String name, int... values) {
    return new TermsQueryBuilder(name, values);
}
public static TermsQueryBuilder termsQuery(String name, long... values) {
    return new TermsQueryBuilder(name, values);
}
...
public static TermsQueryBuilder termsQuery(String name, Object... values) {
    return new TermsQueryBuilder(name, values);
}

when I called termsQuery("operationType","1"), not ambiguous.

when I called termsQuery("operationType",1), ambiguous.

when I called termsQuery("operationType",Arrays.asList(searchParam.getOperatorType()), not ambiguous.

puzzled.....

Upvotes: 8

Views: 3504

Answers (3)

Axel Richter
Axel Richter

Reputation: 61880

All constructors using varargs <any primitive>... are not callable directly using comma separated list of primitives if Object... exists because for all of those Object... is ambiguous. Compiler error message clearly states that.

We could call them using arrays:

termsQuery("operatorType", new int[]{1, 2, 3}).

TermsQueryBuilder termsQuery(String name, Object... values) and TermsQueryBuilder termsQuery(String name, String... values) are not ambiguous because while String is also an Object it is a more special object than just Object.

The following code works and should show what happens exactly:

public class TestAmbiguous {

 public static TermsQueryBuilder termsQuery(String name, int... values) {
    return new TermsQueryBuilder(name, values);
 }
 public static TermsQueryBuilder termsQuery(String name, double... values) {
    return new TermsQueryBuilder(name, values);
 }
 public static TermsQueryBuilder termsQuery(String name, Object... values) {
    return new TermsQueryBuilder(name, values);
 }
 public static TermsQueryBuilder termsQuery(String name, String... values) {
    return new TermsQueryBuilder(name, values);
 }

 public static void main(String[] args) {
  TermsQueryBuilder builder;
  builder = termsQuery("operatorType", 1, 1.0, 1.0f, "test", new Integer(1), new Double(1), new Float(1), new String("test"));
  builder = termsQuery("operatorType", "test", new String("test"));
  builder = termsQuery("operatorType", new int[]{1, 2, 3});
  builder = termsQuery("operatorType", new double[]{1, 2, 3});
  builder = termsQuery("operatorType", new float[]{1, 2, 3});
  builder = termsQuery("operatorType", (Object[]) new Float[]{1f, 2f, 3f});
 }
}

class TermsQueryBuilder {
 TermsQueryBuilder(String name, int... values) {
  System.out.println("_____________________________________");
  System.out.println("primitive int");
  for (int i = 0 ; i < values.length; i++) {
   System.out.println(values[i]);
  }
 }
 TermsQueryBuilder(String name, double... values) {
  System.out.println("_____________________________________");
  System.out.println("primitive double");
  for (int i = 0 ; i < values.length; i++) {
   System.out.println(values[i]);
  }
 }
 TermsQueryBuilder(String name, Object... values) {
  System.out.println("_____________________________________");
  System.out.println("Any objects");
  for (int i = 0 ; i < values.length; i++) {
   System.out.println(values[i].getClass());
   System.out.println(values[i]);
  }
 }
 TermsQueryBuilder(String name, String... values) {
  System.out.println("_____________________________________");
  System.out.println("String objects");
  for (int i = 0 ; i < values.length; i++) {
   System.out.println(values[i].getClass());
   System.out.println(values[i]);
  }
 }
}

Upvotes: 3

Ray Toal
Ray Toal

Reputation: 88378

Simply rename one or both of your methods and the error will go away.

You cannot overload this method with the signatures your desire, because your call can be matched by both method definitions, and the types int and Object are not in a superclass-subclass relationship, so neither is more specific than the other.

Consider

integerTermsQuery

and

objectTermsQuery

EDIT

As you point out in your comments, the version with the String... parameter does not conflict with Object... and arrays are covariant with String being a subclass of Object.

Upvotes: 2

Oleksi
Oleksi

Reputation: 13097

It's ambiguous because 1 can be automatically converted to Integer, which is accepted by the Object signature. It can also be directly accepted by the int signature.

You should make these two methods unambiguous, by either renaming the methods, or not having such a generic argument list (Object...)

Upvotes: 2

Related Questions