Why following program every time prints I'm string
and not I'm object.
or I'm int.
?
public class Demo {
public Demo(String s){
System.out.println("I'm string");
}
public Demo(int i){
System.out.println("I'm int.");
}
public Demo(Object o){
System.out.println("I'm object.");
}
public static void main(String[] args) {
new Demo(null);
}
}
Also if I replace int
with Integer
. It gives error as The constructor Demo(String) is ambiguous.
Why?
A constructor in Java is a special method that is used to initialize objects. The constructor is called when an object of a class is created. It can be used to set initial values for object attributes. In Java, a constructor is a block of codes similar to the method.
A constructor is chosen by matching the number and types of its declared parameters against the number and types of your call's arguments.
The purpose of constructor is to initialize the object of a class while the purpose of a method is to perform a task by executing java code. Constructors cannot be abstract, final, static and synchronised while methods can be. Constructors do not have return types while methods do.
Constructor in C++ is a special method that is invoked automatically at the time of object creation. It is used to initialize the data members of new objects generally. The constructor in C++ has the same name as the class or structure. Constructor is invoked at the time of object creation.
null
can be converted to Object
or String
, but not int
. Therefore the second constructor is out.
Between the conversion to Object
or the conversion to String
, the conversion to String
is more specific, so that's what's picked.
The JLS section 15.12.2 describes method overload resolution, and I believe the same approach is used for constructor resolution. Section 15.12.2.5 describes choosing the most specific method (constructor in this case):
The informal intuition is that one method is more specific than another if any invocation handled by the first method could be passed on to the other one without a compile-time type error.
This about the constructor invocation with Object or String arguments - any invocation handled by new Demo(String)
could also be passed on to new Demo(Object)
without a compile-time type error, but the reverse is not true, therefore the new Demo(String)
one is more specific... and thus chosen by the overload resolution rules.
To answer your second question (since Jon Skeet has already covered the first), when you have both a String
constructor and an Integer
constructor the compiler doesn't know what you mean by null
in new Demo(null)
: it could be either a String
or an Integer
.
Because String
can't be cast to Integer
(and vice versa) the compiler gives up and reports the ambiguous error. This is in contrast to the String
vs Object
choice when you don't have the Integer
constructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With