Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Java prefer to call double constructor?

public class test {
    test(double[] a)
    {
        System.out.println("in double");
    }
    test(Object a)
    {
        System.out.println("in object");
    }
    public static void main(String args[])
    {
        new test(null);
    }
}

In the above code, I pass null as the constructor argument. As null can be anything, the above code compiles fine. When I run the code I expected it to print in object but it prints in double What is the reason behind this?

NOTE the linked question may not be duplicate because this question is related with primitive datatype vs Object

like image 679
rocking Avatar asked Jun 15 '15 16:06

rocking


People also ask

Why we use multiple constructors in Java?

That's the purpose for multiple constructors. To give the programmer flexibility on saying what an object can be created from and which variables need to be initialized in the first place.

Can you have 2 constructors in Java?

The technique of having two (or more) constructors in a class is known as constructor overloading. A class can have multiple constructors that differ in the number and/or type of their parameters. It's not, however, possible to have two constructors with the exact same parameters.

Why is more than one type of constructor required in some classes?

Multiple constructors get used when you want to input varying amounts of initial data for an object. That way you can have a constructor that gives default values and one that accepts user-defined values.

Can we call constructor two times?

Constructors are called only once at the time of the creation of the object.


2 Answers

The reason is that Java interprets null as any type, and when choosing the method to invoke, it will choose the most specific method that first the argument types. Because null can be of the type double[] and a double[] is an Object, the compiler will choose the method that takes a double[]. If the choices involved equally possible yet unrelated types, e.g. double[] and String, then the compiler would not be able to choose a method, and that would result in an ambiguous method call error.

The JLS, Section 4.1, states:

The null reference can always be assigned or cast to any reference type (§5.2, §5.3, §5.5).

In practice, the programmer can ignore the null type and just pretend that null is merely a special literal that can be of any reference type.

like image 111
rgettman Avatar answered Sep 22 '22 16:09

rgettman


Both constructors are applicable, because null is convertible to both Object and double[] - so the compiler needs to use overload resolution to determine which constructor to call.

JLS 15.9.3 uses JLS 15.12.2 to determine the "most specific" constructor signature to use, based on which constructor has the most specific parameter types, according to JLS 15.12.2.5. The exact details are slightly obscure (IMO) but in this case the basic rule of thumb of "if you can convert from T1 to T2, but not T2 to T1, then T1 is more specific" is good enough.

double[] is a more specific type than Object, because there's an implicit conversion from double[] to Object, but not vice versa.

like image 20
Jon Skeet Avatar answered Sep 25 '22 16:09

Jon Skeet