5

Java newbie here; I'm far more comfortable in C#. That said, the following puzzles me. I'm writing some overloaded classes with different parameter signatures in Java. However, it can't seem to distinguish between Object and double. However, it has no problem with Object and Double. Can someone explain what's going on?

public void item(Object a, Object b, String c, String d) {/*Stuff*/}
public void item(double a, double b, String c, String d) {/*Stuff*/}

public void UseIt(double a, double b, Double c, Double d)
{
    item(a, b, someString, someOtherString);   // Claims it's ambiguous
}

or is this just a case of my development system being idiotic?

Sorry about the example; it is like the ones that failed (which I can't really put here), and I made the mistake of not trying it before typing it in...

Bob Webster
  • 153
  • 7
  • 6
    your code actually works for me. I just compiled this class: public class Test { public void item(double a, double b, String c, String d) {/*Stuff*/} public void item(Object a, Object b, String c, String d) {/*Stuff*/} public void UseIt(double a, double b, Double c, Double d) { item(a, b, "", ""); // Claims it's ambiguous } } – Giovanni Caporaletti Jun 07 '13 at 16:47
  • you're passing two doubles to the string arguments! – Giovanni Caporaletti Jun 07 '13 at 16:50
  • Arguments b, c, d are just red herrings. – Jason Sperske Jun 07 '13 at 16:51

3 Answers3

9

This class compiles just fine (just tested to be sure, put it in Test.java and compiled from command line)

public class Test {
    public void item(double a, double b, String c, String d) {/*Stuff*/}
    public void item(Object a, Object b, String c, String d) {/*Stuff*/}
    public void UseIt(double a, double b, Double c, Double d) {
        item(a, b, "", "");   // Claims it's ambiguous
    }
}

Your problem may be related to the fact that you're passing two doubles (c and d) as third and fourth argument, instead of two strings.

Giovanni Caporaletti
  • 5,426
  • 2
  • 26
  • 39
  • 7
    This is the only right answer, which is kind of ironic - "Your problem is wrong". – zw324 Jun 07 '13 at 16:53
  • 1
    I couldn't believe that overloading between value types and boxed types didn't work... I just had to test before answering :D That's also the reason why I have low rep: I don't answer randomly hoping to be right just to score points – Giovanni Caporaletti Jun 07 '13 at 16:55
  • OTOH, if you change both methods to be begin with `Object`, then it does not work. – zw324 Jun 07 '13 at 16:56
4

This is because your IDE (misleadingly, in this case) sees a possible autoboxing.

For instance, if you create a List<Integer>, you can add an int to it: there is autoboxing from int to Integer. Unxobing is the reverse: Integer to int. Note that both boxing and unboxing only apply to numeric primitive types (BUT NOT to arrays of them).

Here, there is no doubt that the method with double will be chosen eventually (since it is more specific), but your IDE considers that there exists a possible ambiguity.

This example code:

public final class Test
{
    public static void item(Object a, Object b, String c, String d)
    {
        System.out.println("Object");
    }

    public static void item(double a, double b, String c, String d)
    {
        System.out.println("double");
    }

    public static void unbox(final double d)
    {
        System.out.println("Unboxed!");
    }

    public static void useIt(double a, double b, Double c, Double d)
    {
        // primitives
        item(a, b, "", "");
        // cast to corresponding classes
        item((Double) a, (Double) b, "", "");
        // objects
        item(c, d, "", "");
        // unboxed by the "unbox" method which takes a "double" as an argument
        unbox(new Double(2.0));
    }

    public static void main(final String... args)
    {
        // Autoboxing of the third and fourth argument
        useIt(1.0, 1.0, 1.0, 1.0);
    }
}

outputs:

double
Object
Object
Unboxed!

Note however that you cannot call:

useIt((Double) a, b, c, d); // No autoboxing of "b"
fge
  • 119,121
  • 33
  • 254
  • 329
-2

Since you have two methods that are the same name with 4 parameters, it is possible that the compiler does not know which method you are referring to. Your call doesn't give a clear definition of which you would like to call. You should change the names of one of the item methods or define the parameters more specifically.

Mike M
  • 752
  • 1
  • 5
  • 13