This question already has answers here:
How does Java choose which constructor to use?
(2 answers)
Closed 6 years ago.
I have a Java class where there are two parameterized constructors
public class TestApplication {
TestApplication(Object o)
{
System.out.println("Object");
}
TestApplication(double[] darray)
{
System.out.println("Array");
}
public static void main(String[] args)
{
new TestApplication(null);
}
}
When I run this program I get output as "Array". Why does the Object constructor not run?
Constructor overloading resolution behaves the same as method overloading resolution. When two constructors match the passed parameter, the one with the more specific argument types is chosen.
null can be assigned to both a double[] and an Object, since both are reference types, but an array is a more specific type than Object (since arrays are sub-classes of the Object class), so new TestApplication(null) triggers the TestApplication(double[] darray) constructor.
Related
This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 6 years ago.
Which overloaded method will be called for the below method and why?
I executed this code and it calls the overloaded method with List but why does it happen?
public class AmbigiousOverload {
public static void add(Object o) {
System.out.println("Overloaded method with Object.");
}
public static void add(List l) {
System.out.println("Overloaded method with List.");
}
public static void main(String[] args) {
add(null);
}
}
Output: Overloaded method with List.
The List overload is called because the List overload is the most specific matching overload, as all List implementations are subclasses of Object.
From JLS Sec 15.12.2.5:
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 error.
Since any parameter you can pass to add(List) can also be passed to add(Object), add(List) is more specific. As such, given that null can be passed to both, the more specific method is the one chosen.
Note that it wouldn't compile if you had an add(String) overload, since List and String are "equally" specific. (Or any other class: it doesn't have to be String).
This question already has answers here:
Overloaded method selection based on the parameter's real type
(7 answers)
Closed 6 years ago.
Why doAction(A a) will be selected in this situation?
Can you advice some articles to read about method selection depending on argument type?
class A { }
class B extends A { }
class D {
void start(A a){
doAction(a);
}
void doAction(A a) {
System.out.println("A action");
}
void doAction(B b) {
System.out.println("B action");
}
}
public class Test {
public static void main(String[] args) {
new D().start(new B());
}
}
Why doAction(A) will be selected in this situation?
Because it's the only applicable method. Overload resolution is performed at compile-time, based on the compile-time type of the arguments.
The doAction(B) method isn't applicable, because there's no implicit conversion from A (the type of your argument) to B (the type of the parameter). You could cast the value to B like this:
doAction((B) a);
At that point both methods would be applicable, but overload resolution would pick doAction(B b) as being more specific than doAction(A a). Of course, it will also fail if you pass in a reference which isn't to an instance of B.
You should read JLS 15.12.2 for the precise details of overload resolution.
This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 7 years ago.
I have the following structure of my class:
void add(String s){
System.out.println("string");
}
void add(Object s){
System.out.println("object");
}
public static void main(String[] args) {
new MyClazz().add(null);
}
O/P : string
Why object is not called?
String is more specific than Object. Therefore void add(String s) is preferred over void add(Object s).
15.12.2. Compile-Time Step 2: Determine Method Signature
The second step searches the type determined in the previous step for
member methods. This step uses the name of the method and the argument
expressions to locate methods that are both accessible and applicable,
that is, declarations that can be correctly invoked on the given
arguments.
There may be more than one such method, in which case the most
specific one is chosen. The descriptor (signature plus return type) of
the most specific method is the one used at run time to perform the
method dispatch.
This question already has answers here:
How is an overloaded method chosen when a parameter is the literal null value?
(8 answers)
Closed 7 years ago.
I have this code:
class SuperClass {
int method(Object o){
return 1;
}
int method(String s){
return 2;
}
}
public class PassingNull extends SuperClass {
int method(Object s) {
return 3;
}
public static void main(String... a){
SuperClass sc = new SuperClass();
PassingNull sb = new PassingNull();
SuperClass st = new PassingNull();
System.out.println(sc.method(null)); //1
System.out.println(sb.method(null)); //2
System.out.println(st.method(null)); //3
}
}
I understand that for 1 and 3, it prints '2' because that most specific parameter type is called. But not able to understand why 2 prints '2'.
Basically, for the same reason as cases 1 and 2.
SuperClass has two methods named method, as you know. One of them takes an Object and the other takes a String, and the latter is more specific -- so passing null refers to the second (more specific) method, since null is applicable to both.
Now, PassingNull also has two methods named method. Like before, one overload takes Object (the one that overrides SuperClass::method(Object)), and the other one takes String (the one that's inherited straight from SuperClass). So it's a similar situation, meaning that the type resolution will work similarly: given that both overloads are applicable, the more specific one -- the one that takes String -- is the one that will get invoked.
This question already has answers here:
Method overloading and choosing the most specific type
(9 answers)
Closed 8 years ago.
class Test {
public Test(Object obj) {
System.out.println("Object");
}
public Test(String s) {
System.out.println("String");
}
public static void main(String[] args) {
new Test(null); //prints String. Why not Object?
}
}
If I add another constructor with argument of type Integer ,or, for that matter any other type, calling new Test(null); results in compilation error - The constructor Test(Object) is ambiguous. Why no error is generated for the above example? On executing it, constructor with argument String is called. Why constructor with argument type Object is not called? How this ambiguity is resolved?
//prints String. Why not Object?
Because compiler choose most specific type.
If I add another constructor with argument of type Integer ,or, for
that matter any other type, calling new Test(null); results in
compilation error - The constructor Test(Object) is ambiguous.
Now String and Integer are in the same level in the object hierarchy, So, compiler can't choose one out of those two
Because it is determined by the most specific type of the parameter.
Since String is subclass of Object, and null is subtype of anything, then the second constructor is called, because String is more specific than Object.
Compiler is designed to pick up the overloaded method that very closely matches the Value sent in parameter.