2012-10-09 36 views
43

這個問題基本上是不言自明的。我一直無法找到數組的API(除了這個Arrays,但這只是定義了一堆用於處理實際數組的靜態輔助函數)。如果沒有它的類,這似乎表明一個數組不能是Object數組是一個原始類型還是一個對象(或者其他的東西)?

但是,數組具有公共字段(如length)以及它可以調用的方法(如.equals().clone())似乎表明(非常強烈)完全相反。

原始數組的奇怪表現和行爲的解釋是什麼?作爲一個說明,我試圖在剛剛使用數組的.clone()方法上使用「Open Implementation」Eclipse功能,希望能夠查看在何處以及如何定義此方法(因爲它表示int []從Object推翻它),但它實際上使我的整個Eclipse來凍結和崩潰...

回答

48

每個陣列類型都有一個類,所以有一個類爲int[],有一個類爲Foo[]。這些類由JVM創建。您可以通過int[].classFoo[].class訪問它們。直接超類,這些類都是Object.class

public static void main(String[] args) 
{ 
    test(int[].class); 
    test(String[].class); 
} 

static void test(Class clazz) 
{ 
    System.out.println(clazz.getName()); 
    System.out.println(clazz.getSuperclass()); 
    for(Class face : clazz.getInterfaces()) 
     System.out.println(face); 
} 

還有一個編譯時亞型規則,如果AB亞型,A[]B[]亞型。

+0

優秀的答案!我現在明白爲什麼我現在找不到任何API或任何東西。這非常有趣,JVM在運行時自己創建這些類。最後一個問題:如果一個數組與其他對象一樣是一個類的成員,那麼初始化是如何工作的?如果你說的是準確的,[]只是類名的一部分,爲什麼他們沒有使用構造函數聲明,即new int [](2)vs new int [2]? – asteri

+0

'int [2]'語法來自C,Java試圖接近C語言。 – irreputable

+0

最有可能的是,jvm中有特殊的代碼來處理數組初始化,這與標準對象實例非常不同。 – Matt

5

所以短期和簡單,是<類型> []是一個類型的Object。據我瞭解,它直接從Object延伸。其上有所有對象方法,toString(),hashCode(),...加上一個特殊的暴露變量,稱爲length。類java.util.Arrays是用於處理數組類型的實用程序類。當你添加到亂七八糟的東西時有點令人困惑:int[]不會從Object[]繼承。另外,與其他Object類型不同,沒有數組類型的構造函數。他們尊重new關鍵字,但通常是爲了分配大小。這有點奇怪,但只是其中一種語言怪癖。

要回答這個問題,是的,他們是一個對象。

+0

數組是一個對象...但是int []不能從Object繼承?這讓我困惑。我也因爲沒有構造函數而感到困惑,因爲我們使用'new' ...這是如何工作的?原始數組基本上是一個Object和一個硬連線原語之間的交叉...? – asteri

+1

no int []不從Object []繼承。像int []和Object [],String [] ...都是不同的,因爲它們都從Object繼承,而不是Object []。泛型幫助編寫採用數組的方法,以及我剛纔提到的Arrays實用程序類,但是這種奇怪的怪癖導致了一些時髦的代碼,有時只是爲了讓類型排隊 –

+0

如果int []不從Object繼承並且int []不是一個原語,它是什麼? Java的主要格言(所有對象是否擴展Object)都不完全正確,並且數組是屬於一個單獨的對象類別? – asteri

13

請參閱下面的代碼。它編譯: -

int[] arr = new int[2]; 
    System.out.println(arr.toString()); 

現在,任何原始類型,你不能調用Object類(或者,對於這個問題的任何方法)中定義的方法(toString())。所以,數組本質上是一個Object。 。

OK,在這裏你去: -

JLS Section 4.3: -

有4種引用類型:類類型(§8),接口 類型(§9),類型變量(§4.4)和數組類型(§10)。

而且,Section 10: -

在Java編程語言中,陣列是(第4.3.1節),是 動態創建的對象,並且可以被分配給Object類型 的變量(§ 4.3.2)。可以在數組上調用Object類的所有方法。

所以,從第一次報價,Array實際上不是一類。它是另一種類型的。但是,實質上是數組是對象,雖然不是一些Class,但他們Array型的。所以他們不是某個類的實例,可能是array對象被定義爲創建方式..

+0

我知道。我以前使用過數組。剛纔想到的問題是,在意識到數組的行爲與實際的常規對象有何不同之處。例如,在你的「新」聲明中,你不使用'new int [2]()'...因爲它不是一個真正的構造函數。爲什麼? API在哪裏?什麼是解釋?它不如你做得那麼簡單。 – asteri

+1

我想知道如果有人不喜歡我的回答,以便我可以改善它,而不是隻看到它downvotes .. –

+0

@Jeff ..我編輯我的帖子,使其更明智..你可以看看.. –

25

Java Language Specification應該給你一個想法:

數組類型的直接超類是Object。

每種陣列類型都實現了接口Cloneablejava.io.Serializable

Moreover

一個對象是一個類的實例或陣列。

因此,數組不是實例,因此您不需要構造函數來創建它們。而是使用Array Creation Expressions

+0

也許我正在推翻這個......但是如何能夠不是一個類或者一個類的成員仍然擴展'Object'? – asteri

+1

@Jeff我無法真正回答這個問題。也許[this](http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html#jls-10.7)有幫助。此外,還有一個有趣的答案[這裏](http://stackoverflow.com/questions/2267790/how-are-arrays-implemented-in-java)。 – Baz

+0

@Jeff'int []'是一類 – irreputable

0

只有那些Java中的幾種基本類型,如我們所知。基本上,我們仍然有幾個步驟來創建一個數組,如聲明,構造或初始化(如果需要),這意味着數組確實是一個對象。

更深層次上,原始類型可以用原始值存儲在內存中,但對象是地址(引用)。所以我們可以想象一個悖論,如果數組是原始類型,我們如何將原始值存儲在內存中?我認爲和String相同,但String是最後一個對象,所以你可以用簡單的方式構造一個對象,String s =「s」,就像一個基本類型一樣。

相關問題