Qual è la differenza tra la variabile oggetto non inizializzata e la variabile oggetto inizializzata su null in Java


12

Ho le seguenti due variabili oggetto

Date a;
Date b=null;

Sicuramente sia "a" che "b" non si riferiscono ad alcun oggetto.

Ora, se invoco la seguente dichiarazione

System.out.println(a.toString());

Ci sarà un errore di compilazione, mentre se invoco la seguente dichiarazione

System.out.println(b.toString());

Non ci saranno errori durante la compilazione ma ci sarà un errore di runtime. Qual è la ragione di ciò e quale valore verrà effettivamente archiviato in 'b' per rappresentare un valore nullo?


2
chiesto e risposto più volte a SO: Perché le variabili locali non sono inizializzate in Java? , Variabili non inizializzate e membri in Java e in molte domande ad esse collegate
moscerino

@gnat, hai qualche altra domanda sulla differenza tra "non inizializzato" e "null"? Solo perché la risposta è simile non significa che questa è una domanda duplicata.
DougM,

@DougM certo, hai letto la prima domanda che ho fatto? "C'è stato qualche motivo per cui i progettisti di Java hanno ritenuto che alle variabili locali non dovesse essere assegnato un valore predefinito? Davvero, se alle variabili di istanza può essere assegnato un valore predefinito, allora perché non possiamo fare lo stesso per le variabili locali?" (FWIW tecnicamente non può essere un duplicato, semplicemente perché si trova in un altro sito)
moscerino

1
Ciò non risolve la differenza tra "non inizializzato" e "inizializzato come null", ma solo "perché le variabili non vengono automaticamente inizializzate su null?" Stesso argomento, domanda leggermente diversa.
DougM,

Risposte:


3

Questo perché lo stato delle variabili locali è controllato nel suo ambito

 // method/loop/if/try-catch etc...
 {
   Date d; // if it's not intialised in this scope then its not intialised  anywhere
 }

Non è il caso dei campi

class Foo{
 Date d; // it could be intialised anywhere, so its out of control and java will set to null for you
}

Ora, perché va bene impostare una variabile su null e usarla immediatamente? forse questo è un errore storico che a volte porta a errori orribili

 {
  Date d = null;
  try{
  }catch{ // hide it here 
  }
  return d;
 } 

Ora qual è la differenza semantica?

Date d;

dichiara semplicemente una variabile che può contenere un riferimento che punta a un oggetto di tipo Date, tuttavia

Date d= null; 

fa esattamente lo stesso ma questa volta il riferimento punta a null, null è come qualsiasi riferimento, occupa uno spazio di un puntatore nativo, ovvero 4 byte su macchine a 32 bit e 8 byte su macchine a 64 bit


questo sembra semplicemente ripetere il punto sollevato e spiegato in una risposta precedente pubblicata un'ora fa
moscerino del

@gnat Grazie per il tuo commento, ma non credo lo sia, evviva
Sleiman Jneidi,

Vuoi dire che null è anche un oggetto memorizzato da qualche parte nella memoria e tutte le variabili oggetto assegnate con null puntano a quell'oggetto null.
Harish_N

@ Harish.N no, non l'ho detto, ho detto che è un riferimento e non un oggetto
Sleiman Jneidi,

Nell'esempio che hai fornito 'd' è un riferimento .. è un riferimento a un oggetto di tipo Date ... allo stesso modo se null è un riferimento .. a quale oggetto si riferisce a ...?
Harish_N

19

Non c'è differenza per i campi di classe. Sono nulldi default per gli oggetti, 0 per i valori numerici e falseper i valori booleani.

Per le variabili dichiarate nei metodi - Java richiede che siano inizializzate. La mancata inizializzazione causa un errore di compilazione quando si accede.

Per quale motivo? I campi di classe possono essere modificati con qualsiasi metodo. In qualsiasi ordine viene invocato il metodo. Tutti i campi non privati ​​possono essere modificati da altre classi e / o classi che estendono quella classe. Quindi, non ha senso notificare una variabile non inizializzata, poiché può essere assegnata in molti, molti posti.

Le variabili all'interno dei metodi, tuttavia, sono locali e possono essere modificate solo all'interno del metodo stesso. Quindi è sia possibile che razionale indicare possibili errori. E il compilatore prova a farlo. Se sa che il campo non è inizializzato, mostrerà un errore, perché non è mai quello che vuoi. Se non è sicuro, emetterà un avviso, in modo che tu possa esserne sicuro.

public static class Test {
    Date a; // ok 
    Date b = null; // ok

    public void test() {
        Date c;
        Date d = null;

        System.out.println(a.toString());
        System.out.println(b.toString());
        System.out.println(c.toString()); // error
        System.out.println(d.toString()); // warning
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.