2013-03-21 28 views
3

假設有是一個整數陣列在我的類:Java對象陣列的存儲器需求

public class Foo { 
    private Integer[] arr = new Integer[20]; 
    ..... 

} 

在64位架構此的空間需求是〜(20 * 8 + 24)+ 24 * 20 {空間需要引用+一些數組開銷+對象所需的空間}。

爲什麼java存儲對所有20個Integer對象的引用?不知道第一個內存位置和數組中的項數是否足夠? (假設我也在閱讀某個數組中的對象被連續放置的地方)。我想知道這種實施的原因。對不起,如果這是一個不好的問題。

+0

如果你想要做Integer i = arr [3];'?你想引用確切的對象,而不是'arr + 3',因爲這個數組可能會在稍後被GC化。 – 2013-03-21 14:44:29

+0

在Java中,所有東西都必須先初始化,然後才能真正開始使用它。默認情況下,引用類型數組的所有元素都被初始化爲'null'。 – 2013-03-21 14:48:20

+0

該數組僅保存引用的空間,初始化爲'null'。你還沒有創建任何'Integer'對象。 – GriffeyDog 2013-03-21 14:51:13

回答

2

和其他class一樣,Integer是參考類型。這意味着它只能通過引用間接訪問。你不能在一個字段,一個局部變量,一個集合中的一個槽中存儲一個引用類型的實例 - 你總是必須存儲一個引用並單獨分配這個對象本身。這有多種原因:

  • 您需要能夠代表null
  • 您需要能夠將其替換爲子類型的另一個實例(假定子類型是可能的,即類別不是final)。例如,一個Object[]實際上可能存儲任意數量的不同類的實例,其大小變化很大。
  • 您需要保留共享,例如a[0] = a[1] = someObject;全部三個必須參照相同對象。如果對象是可變的,這更重要(甚至重要),但即使對於不可變對象,差異也可以通過引用相等檢查(==)觀察到。
  • 您需要引用賦值爲原子(參見Java內存模型),因此複製整個實例比看起來更昂貴。

有了這些和許多其他約束條件,始終存儲引用是唯一可行的實施策略(通常)。在非常特殊的情況下,JIT編譯器可能會避免完全分配一個對象並直接存儲它(例如在堆棧上),但這是一個模糊的實現細節,並且不能廣泛適用。我只是爲了完整性而提及這一點,因爲它是「假設」規則的絕妙例證。