簡體   English   中英

Java中的對象類型和引用數組

[英]Object type in Java and referencing arrays

public class RefMix {
  public static void main(String[] args) {
    Object[] a = {null, "foo"};
    Object[] b = {"bar", b};
    a[0] = b;

    System.out.println(a[0][0]);
  }
}

我的理解是數組是Java中的對象,因此是Object類型的子類。 我的進一步理解是,2-dim數組被實現為對數組的引用數組。 因此我不明白為什么我的a [0] [0]在上面的代碼中沒有產生bar 相反它不編譯:

RefMix.java:7: array required, but java.lang.Object found

我的理解是數組是Java中的對象,因此是Object類型的子類。 我的進一步理解是,2-dim數組被實現為對數組的引用數組。

這一切都是正確的,並解釋了為什么你可以完成任務

a[0] = b;

沒有編譯器的任何投訴。

因此我不明白為什么我的a [0] [0]在上面的代碼中沒有產生條形。

好的,我們來看看這個表達式中的類型:

  • aObject[] - 它是Object的數組
  • a[0]是一個Object
  • a[0][0] - 現在您嘗試在Object上使用數組下標。 編譯器不知道Object實際上是一個數組,因此它會抱怨。

對象實例的運行時類型與靜態推斷類型不同。 編譯器將嘗試估計程序中每個變量的類型,以便盡早捕獲某些類型的錯誤。 在這種情況下, a[0]將始終是一個數組,但編譯器不知道這一點。 由於您從對象數組中獲取對象,因此所有編譯器都知道a[0]是一個對象。 因此它會引發錯誤。

如果你知道某些東西總是某種類型,但是編譯器無法解決它,你可以通過插入一個顯式的強制轉換來解決這個問題。

System.out.println(((Object[])a[0])[0]);

你是對的,數組總是Java中的Objects ,但是Objects並不總是數組,因此你得到一個編譯錯誤,因為a是一個Object[] (一維)。 你無法訪問

a[0][0];

因為a不是二維數組(至少它不是這樣聲明的)。 但是在這種情況下,您確定a[0]是一個Objects數組。 因此,您可以這樣做:

Object[] c = (Object[]) a[0];
System.out.println(c[0]);
// or directly:
System.out.println(((Object[])a[0])[0]);

會將 a[0]Object )的返回類型轉換為Object[] ,然后您可以訪問該數組的“第二層”。

由於Java中的數組是一個對象,所以第一個和第二個賦值將把你的數組存儲為Object數組的第一個元素。

Object[] a = {null, "foo"};
Object[] b = {"bar", b};

現在,您已經更改a對象數組的第一個元素以包含值b而不是數組..但是因為它是一個對象數組。 從它出來的一切都將是對象..

因為[0]是一個對象..所以,你顯然無法訪問這樣的東西: -

System.out.println(a[0][0]);

您可以嘗試將對象a [0]強制轉換為對象數組..: -

System.out.println(((Object[])a[0])[0]);

做:

System.out.println(((Object[])a[0])[0]);

這將在運行時將對象“轉換”為對象數組。

由於我最近進行了大量的C ++編碼,我發現Java在類型檢查方面比C ++更嚴格。 Java認為除了原始類型之外的所有東西都是Object,但Java在區分Array和非Array類型方面更進了一步。 在分配期間,如“a [0] = b;” ,Java首先檢查它是否是一個Array類型,之后它會經歷常規的多態類型檢查過程。 如果你想讓你的代碼工作,你應該做...

Object[][] a = {{null}, {"foo"}};
Object[] b = {"bar", new java.util.Date()};
a[0] = b;

您可以通過查看作為參數傳遞給Class.forName()的Java類簽名來了解java如何特別注意數組類型。 例如,數據類型..

com.foo.Bar[][] barsIn2D;

可以在下方加載簽名...

// [ => Array
// [[ => Array of Array type
// L<object>; => Object, not Array
Class.forName("[[Lcom/foo/Bar;");

如您所見,簽名以'['或'L'開頭。 這告訴我們它的數組是否優先於“Lcom / foo / Bar;”。

你正在做的一切都等同於此

Object a = {"bar", "foo"};
System.out.println(a[0]);

哪個也不編譯。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM