類數組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) 數組作為返回值:首先,既然數組是對象,那麼就可以把這個對象作為返回值;而且,不必擔心那個數組的是否可用只要需要它就會自動存在而且垃圾收集器會在我們完成後自動將其清除
Ⅱ java類中構造函數中:數組怎樣初始化
1、java構造函數--數組 在構造函數中初始化數組,如 public class array { private int [][] matrix; public array(int r,int c) { matrix=new matrix[r][c]; } }
matrix=new matrix[r][c];
2、這里是new int[][]; java中8個基本數據類型都是有默認值的,int默認值為0 ,
3、所以數組中默認都為0.
4、但是切記有默認值的變數必須是類的屬性,方法中局部變數必須賦值才可以使用。
Ⅲ JAVA中數組分為哪幾類
可變長度和不可變長度。不可變長度的是一般的數組,可以自定義聲明的,這類數組初始化之前必須聲明長度,例如 int [] aa = new int[20]; ,String str[] = new String[10]; ;另一種是可變長度的,這類不需要定義,是java語言提供的,也就是集合,但不全是,確切的說是集合的一部分,像ArrayList、Vector,其存儲數據的方式是以數組形式存儲的。建議看一下java編程的相關資料書。
Ⅳ java類怎樣定義數組對象數組
public class a {
public static void main(String[]args){ int a[]={3,9,8};//這個是數組的靜態初始化. Date days[]={new Date(1,4,2994),new Date(2,4,2004),new Date(2,5,2005)};
//創建了3個Date對象放在days[]數組里。 //這里還有種寫法。你可以先定義個數組,然後動態的進行付值。 //這樣寫可能煩了點,你也可以用for循環來進行動態賦值。 //列:Date days[]; // days=new Date[3]; // days[0]=new Date(1,2,3); // days[1]=new Date(1,2,3); // days[2]=new Date(1,2,3);
for(int i=0;i<days.length;i++){ //循環數組里的對象
//將對象中的a屬性列印輸出。