Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't Java distinguish between objects and numbers? [duplicate]

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...

like image 387
Bob Webster Avatar asked Jun 07 '13 16:06

Bob Webster


2 Answers

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.

like image 74
Giovanni Caporaletti Avatar answered Oct 14 '22 00:10

Giovanni Caporaletti


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"
like image 28
fge Avatar answered Oct 14 '22 00:10

fge