2012-01-19 28 views
5

Este es un código simple¿Es una referencia nula una instancia de una clase?

class Foo { 
} 

class Bar extends Foo { 
} 

public class Main { 

public static void main(String[] args) throws Exception { 
    fn(null); 
} 

static void fn(Foo f) { 
    System.out.println(f instanceof Foo ? "Foo" : "Bar"); 
} 
} 

Mi pregunta es: ¿Cómo sabe que el Java nula pasada es Bar y no Foo? Sé por qué el compilador elige Bar y no Foo (porque hay una conversión de foo a bar y de bar a foo y no viceversa). Pero, ¿cómo sabe el método que este nulo proviene de Bar y no de Foo? ¿contiene null información sobre el objeto al que está asignado?

+0

Null no puede ser Bar o Foo. Es nulo –

Respuesta

23

Lo estás leyendo de la manera incorrecta. instanceofsiempre evalúa a false para null referencias.

Desde el (el énfasis es mío) Java specification:

En tiempo de ejecución, el resultado del operador instanceof es cierto si el valor de la RelationalExpression no es nulo y la referencia podría ser lanzado (§15.16) al ReferenceType sin generar una ClassCastException. De lo contrario, el resultado es falso.

+0

Quizás más porque 'null' no es una instancia. Sin embargo, nulo se puede asignar a cada clase. –

+0

+1 respuesta perfecta. – apines

1

Siempre es falso. Javac lo sabe.

Pero puede usar f.someStaticFunctionOfTheClassFoo(). Entonces, tu pregunta es muy interesante, solo necesita ser editada.

+1

No veo cómo mencionar los métodos estáticos es útil aquí. –

1

¿Es una referencia nula una instancia de una clase?

Seamos claros acerca de esto. Una referencia no es una instancia de nada. Es una referencia. El objeto al que se refiere, si lo hay, es una instancia de alguna clase. Pero la referencia nula no se refiere a ningún objeto.

Mi pregunta es: ¿Cómo sabe Java que el nulo pasado es Bar y no Foo?

No lo es. Tu programa te mintió. Imprime "Barra" si la referencia no se refiere a una instancia de Foo. Pobre codificación de tu parte.

Sé por qué el compilador elige Bar y no Foo (porque hay una conversión de foo a bar y de bar a foo y no viceversa).

El compilador no tenía ninguna opción. Su código hizo una prueba e impresión mal diseñadas.

Pero, ¿cómo sabe el método que este nulo proviene de Bar y no de Foo?

No lo es. Adivinó. Lo entendió mal.

Qué contiene nula alguna información sobre el objeto que se asigna a?

No contiene ninguna información.

+0

Resultó ser un idiota cuando hice esta pregunta :) –

+1

@SleimanJneidi No seré tan grosero como para estar de acuerdo, pero siempre es bueno poder reconocer tus propios errores. – EJP

0

null es un tipo especial y ese tipo especial es "NullType".

Cuestiones relacionadas