Understanding which constructor is chosen and why

前端 未结 4 1079
庸人自扰
庸人自扰 2020-12-03 15:49

Why following program every time prints I\'m string and not I\'m object. or I\'m int.?

public class Demo {

    public         


        
相关标签:
4条回答
  • 2020-12-03 15:56

    The fact the String constructor is mentioned in by the compiler in your second error:

    The constructor Demo(String) is ambiguous.
    

    is not significant. This is because the Constructor which takes a String is the first declared constructor, so the compiler uses it in its error message. Change to have the Object constructor first and you get:

    The constructor Demo(Object) is ambiguous.
    

    What it's trying to say is there's ambiguity between the constructor which takes the Integer and the Object, so you have to be more specific, as null can be applied to each. Integer IS-NOT-A String, so the two types are not compatible. You need to be more specific so the compiler can bind the constructor call.

    See @Jon Skeet answer for why the compiler raises an error in some instances and not in others.

    0 讨论(0)
  • 2020-12-03 15:58

    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.

    0 讨论(0)
  • 2020-12-03 16:15

    When you have constructors or methods like the above, the compiler generally tries to find the closest match possible and uses that.

    The way to think of null in these circumstances is it acts as a subtype of all types (yes, it's not strictly speaking true but it provides a good platform for thinking about what happens). So using this rule it fits string more closely than object, hence this is the constructor that is executed.

    0 讨论(0)
  • 2020-12-03 16:16

    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.

    0 讨论(0)
提交回复
热议问题