java數組中的對象
❶ 如何用java定義數組類型的對象
一般定義數組有很多種,我只舉一個基本類型,如下:
int [] arr = new int[這里給數組一個長度];或者 int [] arr = {這里直接給數組賦值};
不管用哪一種定義數組,arr就是數組類型的對象。你可以操作其數組:arr[0] = 1;這樣就是給數組賦值,如果是第二種定義就是修改掉原先數組的值。
希望能幫到你!
❷ 關於JAVA數組的幾點注意事項與一些低級錯誤
關於JAVA數組的幾點注意事項與一些低級錯誤
1、數組不是集合,它只能保存同種類型的多個原始類型或者對象的引用。數組保存的僅僅是對象的引用,而不是對象本身。
2、數組本身就是對象,Java中對象是在堆中的,因此數組無論保存原始類型還是其他對象類型,數組對象本身是在堆中的。
3、數組聲明的兩種形式:一、int[] arr; 二、int arr[]; 推薦使用前者,這符合Sun的命名規范,而且容易了解到關鍵點,這是一個int數組對象,而不是一個int原始類型。
數組初始化可以在聲明是進行,int[] arr = {1,2,3}或者int[] arr = new int[3]{1,2,3}。
4、在數組聲明中包含數組長度永遠是不合法的!如:int[5] arr; 。因為,聲明的時候並沒有實例化任何對象,只有在實例化數組對象時,JVM才分配空間,這時才與長度有關。
5、在數組構造的時候必須指定長度,因為JVM要知道需要在堆上分配多少空間。反例:int[] arr = new int[];
6、多維數組的聲明。int[][][] arr; 是三維int型數組。
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'。(無論該數組是成員變數還是局部變數)
9、對象類型數組中的引用被默認初始化為null。如:Car[] myCar = new Car[10]; 相當於從myCar[0]到myCar[9]都這樣被自動初始化為myCar[i] = null;
10、對象類型的數組雖然被默認初始化了,但是並沒有調用其構造函數。也就是說:Car[] myCar = new Car[10];只創建了一個myCar數組對象!並沒有創建Car對象的任何實例!
11、多維數組的構造。float[][] ratings = new float[9][]; 第一維的長度必須給出,其餘的可以不寫,因為JVM只需要知道賦給變數ratings的對象的長度。
12、數組索引的范圍。數組中各個元素的索引是從0開始的,到length-1。每個數組對象都有一個length屬性,它保存了該數組對象的長度。(注意和String對象的length()方法區分開來,這兩者沒有統一起來是很遺憾的。)
13、Java有數組下標檢查,當訪問超出索引范圍時,將產生運行時異常。注意,這種下標檢查不是在編譯時刻進行的,而是在運行時!也就是說int[] arr = new int[10]; arr[100] = 100; 這么明顯的錯誤可以通過編譯,但在運行時拋出!
Java的數組下標檢查是需要額外開銷的,但是出於安全的權衡還是值得的,因為很多語言在使用數組時是不安全的,可以任意訪問自身內存塊外的數組,編譯運行都不會報錯,產生難以預料的後果!
❸ java 數組也算一個類嗎
不管在其他語言中是什麼,數組在Java中可得看作一個對象,它有一些值得探討的特性。
Java中的數組其實是一個對象,但是確實是一個特殊的對象,實在是太特殊了,以致我們都不好把它多做對象處理。
java是純面向對象的語言,數組也是一個對象。
首先我們看一下表面現象,數組創建的時候採用的是如下語句:
MyClass[] arr = new MyClass[9];
而普通類採用的是如下語句:
MyClass obj = new MyClass();
就是說,創建數組的時候不使用小括弧傳參。使得數組和普通類看起來就有很多不同,因為小括弧里的參數是傳遞給構造方法的,進而讓人感覺數組類是沒有構造方法的。
2)java中數組是對象的依據:
數組的父類是Object,
new Object[0].getClass().getSuperClass() 是Object.class
數組沒有對應的類文件,String對應String.class.數組卻沒有,而且他們的 類名字很古怪,可以這樣獲得 new int[2].getClass().getName();
這是和其他對象最大的不同點,因為數組類是在運行時生成的。
java.lang.reflect.Array是final的,所以數組肯定不是它的子類,這個類用來動態生成數組或者操作數組(獲得長度等)
再往深了想,還有很多讓人感覺不自然的東西。可以肯定的是,java確實將數組作為了一個類來處理。還是用上面的例子說明:
可以通過以下方法得到MyClass[]的Class實例:arr.getClass()或MyClass[].class。這樣,我就可以向數組類裡面「窺探」了。
Class clazz = MyClass[].class;
System.out.println(clazz.getConstructors().length);
列印出來的結果是0;證明數組類確實沒有構造方法。
數組類的「廬山真面目」:
System.out.println(clazz);
輸出是:
[Larraytest.MyClass
對Java
Class文件結構稍有了解就知道,這個字元串的意思就是一個元素類型為arraytest.MyClass的一維數組。也就是說,數組類型不是和普通類
一樣,以一個全限定路徑名+類名來作為自己的唯一標示的,而是以[+一個或者多個L+數組元素類全限定路徑+類來最為唯一標示的。這個()也是數組和普通
類的區別。而這個區別似乎在某種程度上說明數組和普通java類在實現上有很大區別。因為java虛擬機(java指令集)在處理數組類和普通類的時候,
肯定會做出區分。我猜想,可能會有專門的java虛擬機指令來處理數組。
分析到這里,基本上可以肯定:java對數組對象化的操作的支持是指令級的,也就是說java虛擬機有專門針對數組的指令。數組的Class類實例是java虛擬機動態創建動態載入的,其結構與普通java類的Class實例有一些不同。
JDK API中有一個java.lang.reflect.Array類,這個類提供了很多方法(絕大多數是native方法,這在另一個方面證明了java對數組的支持是專用指令支持的,否則用本地方去幹嘛,用來彌補我們對數組操作的局限性。
下面這句話用來創建一個一維的、長度為10的、類型為arraytest.MyClass的數組:
arraytest.MyClass[] arr = (arraytest.MyClass[]) Array.newInstance(arraytest.MyClass, 10);
下面這句話用來創建一個二維的、3乘5的、類型為arraytest.MyClass的數組:
int[] arrModel = new int[]{3,5};
Object arrObj = Array.newInstance(Sub.class, arrModel);
當然你可以用一個數組的引用指向上面的二維數組,這里我們用一個Object的引用指向他。
使用的時候,我們也是可以利用Array類提供的方法來實現:
System.out.println(Array.getLength(arrObj);//第一維長度為3
System.out.println(Array.getLength(Array.get(arrObj, 2)));//第二維長度為5,這里如果寫3,就會得到你意想之中的java.lang.
列印結果是如我所想的:
3
5
對於數組的Class類實例,還有一些奇怪的現象:
在運行代碼 java.lang.reflect.Field fieldarr =
clazz.getField("length");的時候,會拋出異常:java.lang.NoSuchFieldException:
length,這似乎在說數組類沒有length這個域,而這個域其實是我們用的最多的一個(也就是說這個域是肯定存在的)。我想關於數組的Class類
實例、數組的實現等,還有很多「貓膩」在裡面。
順便說一句,java數組最多隻能是255維的。這個讓人看到了C的影子,嘿嘿。
「Java把數組當作一個java類來處理」說起來容易,用起來自然,但是細細想來,還是有很多不簡單的地方呀。
從對數組對象的進一步探討,可以稍微了解Java對對象處理的一些方法。首先來看看一維數組的引用名稱的定義:
int[] arr = null;
在這個定義中,arr表示一個可以參考引用自一維數組對象的變數名稱,但是目前將這個名稱參考引用自null,表示還沒有指定這個名稱參考引用自實際的對
象。在Java中,=運算用於基本數據類型時,是將值復制給變數,但當它用於對象時,則是將對象指定給參考引用名稱來參考引用。也可以將同一個對象指定給
兩個參考引用名稱,當對象的值由其中一個參考引用名稱進行操作而變更時,另一個參考引用名稱所參考引用到的值也會變動。下面來看看範例5.8的示範。
ü 範例5.8 AdvancedArray.java
public class AdvancedArray {
public static void main(String[] args) {
int[] arr1 = {1, 2, 3, 4, 5};
int[] tmp1 = arr1;
int[] tmp2 = arr1;
System.out.print("通過tmp1取出數組值:");
for(int i = 0; i < tmp1.length; i++)
System.out.print(tmp1[i] + " ");
System.out.print("\n通過tmp2取出數組值:");
for(int i = 0; i < tmp2.length; i++)
System.out.print(tmp2[i] + " ");
tmp1[2] = 9;
System.out.print("\n\n通過tmp1取出數組值:");
for(int i = 0; i < tmp1.length; i++)
System.out.print(tmp1[i] + " ");
System.out.print("\n通過tmp2取出數組值:");
for(int i = 0; i < tmp2.length; i++)
System.out.print(tmp2[i] + " ");
System.out.println();
}
}
執行結果:
通過tmp1取出數組值:1 2 3 4 5
通過tmp2取出數組值:1 2 3 4 5
通過tmp1取出數組值:1 2 9 4 5
通過tmp2取出數組值:1 2 9 4 5
在這個範例中,通過tmp1名稱改變了索引2的元素值,由於tmp2也引用自同一數組對象,所以tmp2取出索引2的元素值是改變後的值。事實上在範例
5.8中,有三個引用名稱引用自同一個數組對象,也就是arr1、tmp1與tmp2,所以,如果取出arr1索引2的元素,元素值也會是9。
了解到在Java中數組是一個對象,而使用=指定時是將對象指定給數組名來引用,而不是將數組進行復制。如果想將整個數組的值復制給另一個數組該如
何作呢?可以使用循環,將整個數組的元素值遍歷一遍,並指定給另一個數組相對應的索引位置。範例5.10示範了進行數組復制的方法。
Ü範例5.10 ArrayCopy.java
public class ArrayCopy {
public static void main(String[] args) {
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = new int[5];
for(int i = 0; i < arr1.length; i++)
arr2[i] = arr1[i];
for(int i = 0; i < arr2.length; i++)
System.out.print(arr2[i] + " ");
System.out.println();
}
}
執行結果:
1 2 3 4 5
另一個進行數組復制的方法是使用System類提供的array()方法。其語法如下:
System.array(來源, 起始索引, 目的, 起始索引, 復制長度);
範例5.11改寫了範例5.10,使用System.array()進行數組復制,執行結果與範例5.10是相同的。
Ü範例5.11 ArrayCopy2.java
public class ArrayCopy2 {
public static void main(String[] args) {
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = new int[5];
System.array(arr1, 0, arr2, 0, arr1.length);
for(int i = 0; i < arr2.length; i++)
System.out.print(arr2[i] + " ");
System.out.println();
}
}
四、 Java中的數組作為對象帶來的好處
1)越界檢查
2)length field:與傳統的C++中的數組相比,length欄位可以方便的得到數組的大小;但要注意,僅僅可以得到數組的大小,不能得到數組中實際包含多少個元素,因為length 只會告訴我們最多可將多少元素置入那個數組。
3) 初始化:對象數組在創建之初會自動初始化成null,由原始數據類型構成的數組會自動初始化成零(針對數值類型),(Char)0 (針對字元類型)或者false (針對布爾類型)。
4) 數組作為返回值:首先,既然數組是對象,那麼就可以把這個對象作為返回值;而且,不必擔心那個數組的是否可用只要需要它就會自動存在而且垃圾收集器會在我們完成後自動將其清除