Mi sono imbattuto in un comportamento, non sapevo prima, nel codice di follow-up.Differenza di comportamento: membro statico finale inizializzato 'null' e variabile locale finale inizializzata 'null'
consideri il 1 ° caso:
public static void main(String[] args) {
final String str = null;
System.out.println(str.length()); // Compiler Warning: NullPointerAccess
}
Come previsto, il compilatore mi mostra seguente avvertenza str
essere nulla-Null accesso puntatore: La str variabile può essere solo nulla a questo Posizione.
Ora, quando mi sono trasferito quella variabile un statica campo finale inizializzato a nulla:
class Demo {
static final String str = null;
public static void main(String[] args) {
System.out.println(str.length()); // No Compiler Warning
}
}
Ora, compilatore non risulta alcun preavviso. AFAIK, il compilatore dovrebbe sapere che str
è definitivo, non cambierà il suo valore, in qualsiasi punto del codice. E dato che è null
, sicuramente si tradurrà in NullPointerException
in seguito, cosa che fa.
Sebbene, nel primo caso, il compilatore mi avverta correttamente di questo, perché non può identificarlo nel secondo caso. Perché questo cambiamento di comportamento? Il comportamento è lo stesso, se cambio il campo static
nel campo instance
e accedendo utilizzando un'istanza di Demo
.
Ho pensato che questo comportamento potrebbe essere stato specificato in JLS, quindi ho esaminato l'argomento Assegnazione definita, ma non ho trovato nulla relativo a questo problema. Qualcuno può spiegare il cambiamento di comportamento? Sto cercando qualche punto di forza con qualche link a JLS se possibile?
A parte questo, il motivo per cui il compilatore mi mostra solo avvertimento in primo luogo, come credo per lo stesso motivo ho detto sopra, la chiamata di metodo sarà sicuramente buttare NPE in fase di esecuzione, dal momento che il campo può' essere cambiato? Perché non mi ha mostrato un errore del compilatore? Mi aspetto troppo dal compilatore, come sembra abbastanza ovvio, che il risultato di runtime di str.length()
non può essere diverso da NPE
?
Scusate mancante che in precedenza:
sto usando Eclipse Juno, sulla Ubuntu 12.04 con OpenJDK 7.
Il JLS non * di solito * entra nei dettagli degli avvisi molto - è un dettaglio dell'implementazione del compilatore.Non sarei sorpreso se alcuni compilatori * lo facessero * su questo –
@JonSkeet. qualsiasi compilatore si comporti nello stesso modo in entrambi i casi.In entrambi i casi, sto accedendo al metodo su riferimento null definito –
Sì, sarebbe bello farlo - ma sto dicendo che è una questione di come di gran lunga l'attuazione compilatore vuole andare. non mi aspetto che sia nella JLS, e non dico quale compilatore si sta usando. –