標籤:
1. 數組名區別
--------------------------------------
1. java中不用說,本著一切皆對象的原則,所以java中的數組也是對象.那麼數組類是哪個,當然不是java.util.Arrays.詳見Java數組方法的思考
2. 而在c++中數組名其實是一種資料結構,有人會說不是指標嗎,關於這一點見(C++中數組名其實是一種資料結構)。
從上面兩點中我們可以看出java數組名是對象,而c++數組名是資料結構。那麼有人又會問對象和資料結構又有什麼區別呢?詳見資料結構與對象的區別。
2. 原理區別
-----------------------------------
JAVA裡數組的記憶體配置是在堆裡面的,必須用new來分配,而C++裡面是在棧裡面分配的,定義的時候會自動分配。
java中的數組
1、數組不是集合,它只能儲存同種類型的多個原始類型或者對象的引用。數組儲存的僅僅是對象的引用,而不是對象本身。數組聲明的兩種形式:一、int[] arr; 二、int arr[]; 推薦使用前者,這是一個int數組對象,而不是一個int原始類型。
2、數組本身就是對象,Java中對象是在堆中的,因此數組無論儲存原始類型還是其他物件類型,數組對象本身是在堆中的。
4、在數組聲明中包含數組長度永遠是不合法的!如:int[5] arr; 。因為,聲明的時候並沒有執行個體化任何對象,只有在執行個體化數組對象時,JVM才分配空間,這時才與長度有關。
5、在數組構造的時候必須指定長度,因為JVM要知道需要在堆上分配多少空間。例:int[] arr = new int[5];
7、一維數組的構造。形如:String[] sa = new String[5]; 或者分成兩句:String[] sa; sa = new String[5];
8、原始類型數組元素的預設值。對於原始類型數組,在用new構造完成而沒有初始化時,JVM自動對其進行初始化。預設值:byte、short、 int、long--0 float--0.0f double--0.0 boolean--false char--‘"u0000‘。(無論該數組是成員變數還是局部變數)
10、物件類型的數組雖然被預設初始化了,但是並沒有調用其建構函式。(C++中則會調用)也就是說:Car[] myCar = new Car[10];只建立了一個myCar數組對象!並沒有建立Car對象的任何執行個體!
11、多維陣列的構造。float[][] ratings = new float[9][]; 第一維的長度必須給出,其餘的可以不寫,因為JVM只需要知道賦給變數ratings的對象的長度。
12、數組索引的範圍。數組中各個元素的索引是從0開始的,到length-1。每個數組對象都有一個length屬性,它儲存了該數組對象的長度。(注意和String對象的length()方法區分開來)
13、Java有數組下標檢查,當訪問超出索引範圍時,將產生ArrayIndexOutOfBoundsException運行時異常。注意,這種下標檢查不是在編譯時間刻進行的,而是在運行時!也就是說int[] arr = new int[10]; arr[100] = 100; 這麼明顯的錯誤可以通過編譯,但在運行時拋出!
Java中的數組中既可以儲存基本的實值型別,也可以儲存物件。對象數組和未經處理資料類型數組在使用方法上幾乎是完全一致的,唯一的差別在於對象數組容納的是引用而未經處理資料類型數組容納的是具體的數值。在討論關於數組的問題時,一定要先確定數組中儲存的是基本實值型別還是對象。特別是在偵錯工具時,要注意這方面。
3. 類數組是否調用建構函式
-------------------------------------------------
對於上面提到的第10點物件類型的數組雖然被預設初始化了,但是並沒有調用其建構函式。我必須要重點解釋下,因為在c++中會調用其建構函式,這裡最容易搞混。
[java] view plaincopyprint?
- public class Test extends JPanel {
- private static final long serialVersionUID = 4767050156491994899L;
- public static void main(String[] args) {
- AnimApp[] array = new AnimApp[3]; // 沒有執行建構函式, 在這裡只是申請了空間.
- array[0] = new AnimApp(3); // 構造一個對象
- }
- }
-
- class AnimApp {
- public AnimApp(int times) {
- System.out.println("class AnimApp");
- }
- }
看下上面這段java代碼,當執行AnimApp[] array = new AnimApp[3];時並不會調用建構函式,僅僅申請了空間。構造對象的時候才會調用建構函式。
Java中,定義一個數組, new[]時, 並沒有執行建構函式, 只是申請了一段記憶體空間, 與C++中的allocator<T>.allocate(size)(因為allocator<T>的類型在運行時確定, 所以不是指定空間的位元組數, 而是用元素個數, 每個元素的大小allocator中有記錄)相似. 然後在構造一個對象的時候, 即如上new AnimApp(3)時, 才真正的構造對象, 似allocator<T>.construct(param).
C++中, new[]操作符(預設的)就會去先申請空間, 接著執行建構函式, 申請了多少個對象的空間, 執行多少次(每個對象一次), 所以想為無無參建構函式的類使用預設的new[]來定義一個數組是不行的, 這點與Java不同, 他是即申請空間, 同時也要構造對象, Java只是申請一段空間, 對於空間中的每個對象, 得自己顯示的用new ClassName(param)來構造.
對於Java這種與C++不同之處的原因要歸為它們之間的實現不同。
1)Java的數組不是集合,它只能儲存同種類型的多個原始類型或者對象的引用。數組儲存的僅僅是對象的引用,而不是對象本身。
2)數組本身就是對象,Java中對象是在堆中的,因此數組無論儲存原始類型還是其他物件類型,數組對象本身是在堆中的。
3)在Java中,官方推薦的聲明方式是Object []array,並且不能指定長度,只有new的時候才指定長度。
4)物件類型數組中的引用被預設初始化為null。如:Object [] myobj= new Object [10]; 相當於從myobj[0]到myobj[9]都這樣被自動初始化為myCar[i] = null;並沒有調用建構函式。在myobj[1] = new Object的時候才調用。
至於Java為什麼要選擇這種方式,則是其刻意避免指標(容易犯錯),符號都是參考型別。
幾乎所有的程式設計語言都支援數組。在C和C++中使用數組是很危險的。因為C和C++中的數組就是記憶體塊。如果一個程式要訪問其自身記憶體塊之外的數組,或者在數組初始化之前使用它,都會產生難以預料的後果。
java的主要目標之一就是安全性。java確保數組會被初始化,而且不能在它的範圍之外被訪問。這種範圍檢查,是以每個數組上少量的記憶體開銷以及運行時的下標檢查為代價的。但是由此換來的安全性和效率的提高,也是值得的。
當java建立一個數組對象時,實際上就是建立了一個引用數組,並且每個引用都會被自動初始化一個特殊值。該值擁有自己的關鍵字null,一旦java看見了null,就知道這個引用還沒有指向某個對象。如果使用某個指向null的引用,就會在運行時報錯。
Java/C++中數組的區別