2013-05-26 73 views
5

我只是檢查一些OCJP問題,並在字符串數組初始化和異常期間發現了這種差異。沒有初始大小的字符串數組給出空指針異常

案例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(); 
    } 

案例而線4拋出一個零指示字例外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(); 
    } 

行2不會引發任何異常。 雖然第二行確實輸出值爲null

當指定數組的大小和不指定數組的大小時,java是否在初始化的默認值方面有所不同?

回答

5

這臺a的類型,數組的數組:

String[][] a 

當你寫

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

初始化外部陣列,但是你沒有創建內部數組,所以那a[0]null

當你寫

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

運行也產生了內部數組。它描述here in the specification

在運行時,數組創建表達式的評價表現爲 如下:

如果沒有維度表達式,則必須有一個陣列 初始化。

新分配的數組將通過數組初始值設定項提供的值 進行初始化,如§10.6所述。

數組初始值設定項的值成爲數組 創建表達式的值。

否則,沒有數組初始化,並且:

首先,尺寸表達式進行求值,左到右。如果表達式評估的任何 突然完成,則不會評估其表達權的 。

接下來,檢查維度表達式的值。如果任何DimExpr表達式的 值小於零,則會引發 NegativeArraySizeException。

接下來,爲新陣列分配空間。如果 空間不足以分配數組,則通過拋出OutOfMemoryError突出地完成對數組創建 表達式的評估。

然後,如果單個DimExpr中出現時,一維陣列創建指定長度的 ,並且陣列的每個組件是 初始化爲默認(§4.12.5)值。否則,如果出現n個DimExpr表達式,則數組創建 將有效地執行一組深度爲n-1的嵌套循環,以創建暗含的數組數組。

多維數組不需要在每個級別上都有相同長度的數組 。

+0

'並且數組中的每個組件都被初始化爲其默認值' 因此第3行應該分配10個1-D數組並且將'null'賦值爲它的每個元素的權利?第1行也是如此。我對嗎? – redDevil

+1

它將null賦值給'a [0]','a [1]'等,同時第1行給'b [0] [0]','b [0] [1]'賦予null等等。 –

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

相當於:

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

a[0][0]類似於a1[0]會拋出NPE。


你這裏有兩種選擇:

  • 要麼定義數組爲:
String[][] a = new String[3][3]; 
  • 或者創建內部a新的陣列:
a[0] = new String[2]; 
a[1] = new String[4]; 
a[2] = new String[3]; 

注意,使用後者的做法,你將能夠對內部數組大小不同。

1

很好的發現。當你初始化一個二維數組有兩個參數,會發生什麼情況是:

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

2D Array with both bounds

但是當你指定第二個邊界,會發生什麼情況是:

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

2D Array with no inner bound

在您的第4行中,您將得到確切的NullPointerException,因爲:

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

但爲什麼你甚至需要這種行爲?它非常簡單。這適用於二維數組中的每個元素可以具有不同數量的元素的情況。潛在的使用情況是:

enter image description here

而且有相當不錯的使用情況爲這種行爲,如優先級隊列(每個優先級可以有不同數量的隊列中的項目),哈希表(它的溢出部分)等等。