2015-04-06 2 views
3

Я понятия не имею, как задать этот вопрос или какое название использовать. Надеюсь, я не нарушу никаких правил. В любом случае, может кто-нибудь объяснить мне следующее поведение? У меня есть этот код:Java null соответствует Double

X x = new X(); 
x.dosmth(null); 

static class X{ 
     void dosmth(Object obj) { System.out.println("X:Object"); } 
     void dosmth(Double obj) { System.out.println("X:Double"); } 
     void dosmth(int obj) { System.out.println("X:int"); } 
     void dosmth(double obj) { System.out.println("X:double"); } 
     void dosmth(char obj) { System.out.println("X:char"); } 
     void dosmth(byte obj) { System.out.println("X:byte"); } 
} 

Что я получаю это:

X:Double 

Почему он игнорирует полностью нитевидные

void dosmth(Object obj) { System.out.println("X:Object"); } 

И почему нуль соответствует двойной и не объект?

Кроме того, если я добавить строку:

void dosmth(Integer obj) {System.out.println("X:Integer"); } 

я получаю следующее сообщение об ошибке:

both method dosmth(java.lang.Integer) and method dosmth(java.lang.Double) match 

ответ

12

При выборе перегруженного метода, null может соответствовать любому ссылочного типа. Когда есть два кандидата - Object и Double в вашем случае - наиболее конкретный выбирается - Double (Double более конкретно, чем Object, так как это подкласс Object).

Когда вы приведете void dosmth(Integer obj), есть три кандидата - Object, Double и Integer - но так как ни Double, ни Integer более специфичен, чем другой - компилятор не может выбрать между тогда и вы получите сообщение об ошибке.

Как указано FINDarkside, если вы выбрали конкретный метод, вы можете наложить null на нужный тип.

Например, это заставит компилятор выбрать void dosmth(Object obj):

x.dosmth((Object)null); 
+1

Возможно, стоит упомянуть, что вы можете придать null объекту, если это необходимо. – FINDarkside

+0

@FINDarkside Конечно, добавлю. Спасибо – Eran

+0

Это имеет смысл! Спасибо! –

1

Double более специфичен, чем Object. От specification:

If more than one member method is both accessible and applicable to a method invocation, it is necessary to choose one to provide the descriptor for the run-time method dispatch. The Java programming language uses the rule that the most specific method is chosen.

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.

Смежные вопросы