Ankur Mahajan
Ankur Mahajan

Reputation: 3596

String vs. Object type Constructor

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

Answers (2)

SomeJavaGuy
SomeJavaGuy

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

Eran
Eran

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

Related Questions