Reputation: 3596
public class App {
public static void main(String[] args) {
ConTest conTest = new ConTest(null);
}
POJO :
public class ConTest {
private String a;
private Object b;
public ConTest(Object b) {
System.out.println("Object" + b);
}
public ConTest(String a) {
System.out.println("String :" + a);
}
}
When I run this piece of code it always call constructor having String
argument. Why?
Upvotes: 1
Views: 59
Reputation: 7347
The cause of this is, that there are multiple fitting methods (constructor in this case) that do fit the call. If there is more then one fitting method for a method call it allways takes the most specific one. In this case, String
is more specific then Object
.
This can be seen in the inheritance chain. String
inherits from Object
If there are two equally specific methods, then your compiler will tell you so with the error message The method method(parameter) is ambiguous for the type Class
. This can be seen in this example.
public class A {
public static void main(String[] args) {
// compiler complains with:
// The method test(Object) is ambiguous for the type A
test(null);
}
static void test(Object o) {
System.out.println("IN OBJECT");
}
static void test(A a) {
System.out.println("IN A");
}
static void test(B b) {
System.out.println("IN B");
}
class B {
}
}
With a slight change, by letting B
inherit from A
the method test(B)
is getting more specific, because B
is more specific then A
, and the compiler error message is gone.
public class A {
public static void main(String[] args) {
test(null);
}
static void test(Object o) {
System.out.println("IN OBJECT");
}
static void test(A a) {
System.out.println("IN A");
}
static void test(B b) {
System.out.println("IN B");
}
class B extends A{
}
}
Upvotes: 3
Reputation: 393771
null
can be passed to both constructors.
However, a String
argument is more specific than an Object
argument (since String
is a sub-class of Object
), and the method overloading resolution process prefers the method (or constructor in your case) with the more specific argument types.
As mentioned in the comments, if you want to force calling the constructor that accepts an Object
, you can cast the null
to Object
:
ConTest conTest = new ConTest((Object)null);
Upvotes: 5