2012-01-19 4 views
5

Si tratta di un semplice codiceÈ un riferimento null un'istanza di una classe?

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"); 
} 
} 

La mia domanda è: come Java sa che il NULL passata è Bar e non Foo? So perché il compilatore sceglie Bar e non Foo (perché c'è una conversione da foo a bar e da bar a foo e non viceversa). Ma come saprebbe il metodo che questo null proviene da Bar e non da Foo? null contiene alcune informazioni sull'oggetto a cui è assegnato?

+0

Null non può essere Bar o Foo. È nullo –

risposta

23

Stai leggendo nel modo sbagliato. instanceofsempre restituisce false per null riferimenti.

Dalla Java specification (sottolineatura mia):

In fase di esecuzione, il risultato dell'operatore instanceof vale se il valore del RelationalExpression non è nullo e il riferimento potrebbe essere fusa (§15.16) al ReferenceType senza generare ClassCastException. Altrimenti il ​​risultato è falso.

+0

Forse di più perché "null" non è un'istanza. Tuttavia null può essere assegnato ad ogni classe. –

+0

+1 risposta perfetta. – apines

1

È sempre falso. Javac lo sa.

Ma è possibile utilizzare f.someStaticFunctionOfTheClassFoo(). Quindi, la tua domanda è molto interessante, solo che ha bisogno di essere modificata.

+1

Non vedo come menzionare i metodi statici è utile qui. –

1

È un riferimento null un'istanza di una classe?

Diciamolo chiaro. Un riferimento non è un'istanza di qualcosa. È un riferimento L'oggetto che fa riferimento a, se presente, è un'istanza di qualche classe. Ma il riferimento null non si riferisce a nessun oggetto.

La mia domanda è: come sa che il null passato è Bar e non Foo?

Non funziona. Il tuo programma ti ha mentito. Stampa "Bar" se il riferimento non è fare riferimento a un'istanza di Foo. Scarsa codifica da parte tua.

So perché il compilatore sceglie Bar e non Foo (perché c'è una conversione da foo a bar e da bar a foo e non viceversa).

Il compilatore non ha scelto una scelta simile. Il tuo codice ha fatto un test e una stampa mal progettati.

Ma come sarebbe il metodo di conoscere questo nulla viene dal bar e non Foo?

Non funziona. Ha indovinato. Ha sbagliato.

null contiene alcune informazioni sull'oggetto a cui è assegnato?

Non contiene alcuna informazione.

+0

Ho scoperto che ero un idiota quando ho fatto questa domanda :) –

+1

@SleimanJneidi Non sarò così maleducato da essere d'accordo, ma è sempre bene essere in grado di riconoscere i propri errori. – EJP

0

null è un tipo speciale e quel tipo speciale è "NullType".