2012-07-20 23 views
114

static membri (campi static o metodi static) in Java sono associati alla rispettiva classe anziché agli oggetti di questa classe. Il seguente codice tenta di accedere a un campo statico su un riferimento null.Campi statici su riferimento null in Java

public class Main 
{ 
    private static final int value = 10; 

    public Main getNull() 
    { 
     return null; 
    } 

    public static void main(String[] args) 
    { 
     Main main=new Main(); 
     System.out.println("value = "+main.getNull().value); 
    } 
} 

Sebbene main.getNull() rendimenti null, funziona e display value = 10. Come funziona questo codice?

+15

Forse questa domanda può aiutare a capire che: [Come mai invocare un metodo (statico) su un riferimento null non genera NullPointerException?] (Http://stackoverflow.com/questions/3293353/ how-come-invoking-a-static-metodo-on-a-null-riferimento-doesnt-throw-nullpointe? rq = 1) –

+4

Per divertimento, prova 'Main main = null; main.getNull(). value'. –

+1

Questo mi ricorda 'new Thread [] {} [- 1] .sleep (10);' dove sleep() è un metodo statico. Questo ha avuto successo su alcune vecchie versioni di Java. – hertzsprung

risposta

89

Tale comportamento è specificato nella Java Language Specification:

riferimento null può essere utilizzato per accedere ad una variabile di classe (statica) senza causare un'eccezione.

Nel dettaglio, un static field evaluation, come ad esempio Primary.staticField funziona nel modo seguente (sottolineatura mia) - nel tuo caso, Primary = main.getNull():

  • L'espressione primaria viene valutata, e il risultato viene scartato. [...]
  • Se il campo è un campo finale non vuoto, quindi il risultato è il valore della variabile di classe specificata nella classe o nell'interfaccia che è il tipo dell'espressione Primaria. [...]
+5

Se qualcuno ha informazioni su * perché * questa scelta è stata fatta, sarebbe interessante. –

+6

@JonofAllTrades Penso che questo sia ovvio: è ragionevole non fare eccezioni quando si chiama un riferimento null perché non ha importanza poiché il metodo è statico. – Malcolm

+12

@JonofAllTrades: la vera domanda è perché è stata fatta la scelta di consentire il nome di membri statici come istanza ... Per me, sembra solo portare a confusione e codice meno leggibile. – Falanwe

19

Perché, come hai detto, i campi statici non sono associati a un'istanza.

La possibilità di accedere a campi statici da un riferimento di istanza (come si sta facendo) è semplicemente uno zucchero sintattico e non ha alcun significato aggiuntivo.
Il codice viene compilato in

main.getNull(); 
Main.value 
+7

Lo chiamerei zucchero sintattico, più simile alla sega sintattica;) –

3
  1. Accesso a un membro static con il nome della classe è legale, ma la sua non sono stati scritti che non si può accedere al membro static utilizzando la variabile di riferimento oggetto. Quindi funziona qui.

  2. Una variabile di riferimento null scopo viene consentito di accedere a una variabile static classe senza un'eccezione sia in fase di compilazione o eseguire tempo.

3

Quando si accede a una variabile statica oa un metodo con oggetti in fase di compilazione, esso viene convertito in Nome classe. ad esempio:

Main main = null; 
System.out.println(main.value); 

Si stamperà il valore del valore della variabile statica in quanto al momento della compilazione Si verrà convertito in

System.out.println(Main.value); 

Dimostrazione:

scaricare decompilatore e decompilare il file .class a.file java e puoi vedere tutti i metodi statici o il nome di oggetto variabile riferita viene automaticamente sostituito dal nome della classe.

2

La variabile statica e il metodo appartengono sempre alla classe. Quindi, quando mai creiamo qualsiasi oggetto, solo la variabile non statica e i metodi vanno ad accumularsi insieme all'oggetto, ma l'elemento statico risiede nell'area del metodo con la classe. Ecco perché quando proviamo ad accedere a una variabile statica oa un metodo, viene convertito in nome variabile o nome del metodo.

Fare riferimento al collegamento sottostante per ulteriori dettagli.

http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html