[英]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]在上面的代碼中沒有產生條形。
好的,我們來看看這個表達式中的類型:
a
是Object[]
- 它是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.