2013-05-26 1 views
5

Stavo solo controllando alcune domande di OCJP e ho trovato questa differenza durante l'inizializzazione e le eccezioni dell'array di stringhe.L'array di stringhe senza dimensione iniziale fornisce un'eccezione di puntatore nullo

Caso 1

try { 
     String[][] b = new String[10][10];//1 
     System.out.println(b[0][0]);//2 
    } catch (Exception e) { 
     System.out.println("Exception during array 'b' initialization"); 
     e.printStackTrace(); 
    } 

Caso 2

try { 
     String[][] a = new String[10][];//3 
     System.out.println(a[0][0]);//4 
    } catch (Exception e) { 
     System.out.println("Exception during array 'a' initialization"); 
     e.printStackTrace(); 
    } 

Linea 2 non genera alcuna eccezione, mentre la linea 4 genera un'eccezione puntatore nullo. La linea 2 emette il valore come null.

java ha una differenza nei valori predefiniti per l'inizializzazione quando viene specificata la dimensione di un array e quando non lo è?

risposta

5

Questo imposta il tipo di a, come array di array:

String[][] a 

Quando si scrive

String[][] a = new String[10][]; 

si inizializza l'array esterno, ma non si creano le matrici interne, così che a[0] è null.

Quando si scrive

String[][] b = new String[10][10]; 

il runtime crea anche le matrici interne. E 'descritto here in the specification:

In fase di esecuzione, la valutazione di un'espressione creazione dell'array si comporta come segue:

Se non ci sono espressioni di dimensione, allora ci deve essere un array inizializzazione.

Un array appena assegnato verrà inizializzato con i valori forniti dall'inizializzatore di array come descritto in §10.6.

Il valore dell'array di inizializzazione diventa il valore dell'array espressione di creazione.

In caso contrario, non c'è di inizializzazione array, e:

In primo luogo, le espressioni di quota vengono valutate, da sinistra a destra. Se qualsiasi delle valutazioni di espressioni viene completato improvvisamente, le espressioni su non vengono valutate.

Successivamente, i valori delle espressioni di quota vengono verificati. Se il valore di qualsiasi espressione DimExpr è inferiore a zero, viene generata un'eccezione NegativeArraySizeException .

Successivamente, lo spazio viene assegnato per il nuovo array. Se lo spazio non è sufficiente per allocare l'array, la valutazione della creazione dell'array si completa improvvisamente generando un errore OutOfMemoryError.

Quindi, se viene visualizzato un singolo DimExpr, un array monodimensionale viene creato della lunghezza specificata, e ciascun componente della matrice è inizializzato al valore di default (§4.12.5).

Altrimenti, se compaiono espressioni n DimExpr, quindi creazione matrice esegue efficacemente una serie di cicli nidificati di profondità n-1 per creare le matrici implicite di array.

Un array multidimensionale non deve disporre di matrici della stessa lunghezza a ogni livello.

+0

'e ogni componente dell'array viene inizializzato sul suo valore predefinito' in modo che la riga 3 debba assegnare 10' array 1-D' e assegnare 'null' come valore a ciascuno dei suoi elementi, giusto? Lo stesso accade per la Linea 1. Ho ragione? – redDevil

+1

Assegna null a 'a [0]', 'a [1]', ecc. Mentre la riga 1 assegna null a 'b [0] [0]', 'b [0] [1]', ecc. –

1
String[][] a = new String[3][]; 

è equivalente a:

String[] a1 = null; 
String[] a2 = null; 
String[] a3 = null; 
String[][] a = {a1, a2, a3}; 

e a[0][0] è simile a a1[0] che getta NPE.


Hai due opzioni qui:

  • O definiscono la matrice come:
String[][] a = new String[3][3]; 
  • o creare nuovi array all'interno a:
a[0] = new String[2]; 
a[1] = new String[4]; 
a[2] = new String[3]; 

noti che usare quest'ultimo approccio si sarà in grado di avere dimensioni diverse per le matrici interne.

1

Buona scoperta. Se si inizializza un array 2D con entrambi i parametri, ciò che accade è:

String[][] a = new String[5][5] 

2D Array with both bounds

Ma quando non si specificare il secondo limite, ciò che accade è:

String[][] a = new String[5][]; 

2D Array with no inner bound

Nella riga 4, si ottiene l'esatta NullPointerException perché:

String[][] a = new String[10][]; 
System.out.println(a[0][0]); // << a[0] is null! 

Ma perché avresti bisogno di questo comportamento? È abbastanza semplice. È per i casi in cui ogni elemento in una matrice bidimensionale può avere un numero diverso di elementi. Il potenziale scenario di utilizzo caso è:

enter image description here

E ci sono abbastanza buoni casi di utilizzo di questo tipo di comportamento, come code di priorità (ogni priorità può avere un numero diverso di elementi in coda), Hash Table (la parte di overflow di esso), ecc.