国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java數組的特性_動力節點Java學院整理

Java數組的特性_動力節點Java學院整理

2020-09-15 15:22動力節點 Java教程

數組是基本上所有語言都會有的一種數據類型,它表示一組相同類型的數據的集合,具有固定的長度,并且在內存中占據連續的空間。在C,C++等語言中,數組的定義簡潔清晰,而在Java中確有一些會讓人迷惑的特性。本文就嘗試分析

Java中的數組是對象嗎?

Java和C++都是面向對象的語言。在使用這些語言的時候,我們可以直接使用標準的類庫,也可以使用組合和繼承等面向對象的特性構建自己的類,并且根據自己構建的類創建對象。那么,我們是不是應該考慮這樣一個問題:在面向對象的語言中,數組是對象嗎?

要判斷數組是不是對象,那么首先明確什么是對象,也就是對象的定義。在較高的層面上,對象是根據某個類創建出來的一個實例,表示某類事物中一個具體的個體。對象具有各種屬性,并且具有一些特定的行為。而在較低的層面上,站在計算機的角度,對象就是內存中的一個內存塊,在這個內存塊封裝了一些數據,也就是類中定義的各個屬性,所以,對象是用來封裝數據的。以下為一個Person對象在內存中的表示: 

Java數組的特性_動力節點Java學院整理

注意:

1)小的紅色矩形表示一個引用(地址)或一個基本類型的數據,大的紅色矩形表示一個對象,多個小的紅色矩形組合在一塊,可組成一個對象。

2)name在對象中只表示一個引用, 也就是一個地址值,它指向一個真實存在的字符串對象。在這里嚴格區分了引用和對象。

那么在Java中,數組滿足以上的條件嗎?在較高的層面上,數組不是某類事物中的一個具體的個體,而是多個個體的集合。那么它應該不是對象。而在計算機的角度,數組也是一個內存塊,也封裝了一些數據,這樣的話也可以稱之為對象。以下是一個數組在內存中的表示:

Java數組的特性_動力節點Java學院整理

這樣的話, 數組既可以是對象, 也可以不是對象。至于到底是不是把數組當做對象,全憑Java的設計者決定。數組到底是不是對象, 通過代碼驗證:

?
1
2
3
4
5
6
int[] a = new int[4];
//a.length; //對屬性的引用不能當成語句
int len = a.length; //數組中保存一個字段, 表示數組的長度
//以下方法說明數組可以調用方法,java中的數組是對象.這些方法是Object中的方法,所以可以肯定,數組的最頂層父類也是Object
a.clone();
a.toString();

在數組a上, 可以訪問他的屬性,也可以調用一些方法。這基本上可以認定,java中的數組也是對象,它具有java中其他對象的一些基本特點:封裝了一些數據,可以訪問屬性,也可以調用方法。所以,數組是對象

而在C++中,數組雖然封裝了數據,但數組名只是一個指針,指向數組中的首個元素,既沒有屬性,也沒有方法可以調用。如下代碼所示:

?
1
2
3
4
5
6
int main(){
 int a[] = {1, 2, 3, 4};
 int* pa = a;
 //無法訪問屬性,也不能調用方法。
 return 0;
}

所以C++中的數組不是對象,只是一個數據的集合,而不能當做對象來使用。

Java中數組的類型

Java是一種強類型的語言。既然是對象, 那么就必須屬于一個類型,比如根據Person類創建一個對象,這個對象的類型就是Person。那么數組的類型是什么呢?看下面的代碼:

?
1
2
3
4
5
6
7
8
9
int[] a1 = {1, 2, 3, 4};
System.out.println(a1.getClass().getName());
//打印出的數組類的名字為[I
String[] s = new String[2];
System.out.println(s.getClass().getName());
//打印出的數組類的名字為 [Ljava.lang.String;
String[][] ss = new String[2][3];
System.out.println(ss.getClass().getName());
//打印出的數組類的名字為 [[Ljava.lang.String;

打印出a1的類型為[ I ,s 的類型是[Ljava.lang.String;  ,  ss的類型是[[Ljava.lang.String; 

所以,數組也是有類型的。只是這個類型顯得比較奇怪。你可以說a1的類型是int[],這也無可厚非。但是我們沒有自己創建這個類,也沒有在Java的標準庫中找到這個類。也就是說不管是我們自己的代碼,還是在JDK中,都沒有如下定義:

?
1
2
3
4
5
public class int[] {
 // ...
 // ...
 // ...
}

這只能有一個解釋,那就是虛擬機自動創建了數組類型,可以把數組類型和8種基本數據類型一樣, 當做java的內建類型。這種類型的命名規則是這樣的:

* 每一維度用一個[表示;開頭兩個[,就代表是二維數組。

* [后面是數組中元素的類型(包括基本數據類型和引用數據類型)

在java語言層面上,s是數組,也是一個對象,那么他的類型應該是String[],這樣說是合理的。但是在JVM中,他的類型為[java.lang.String。順便說一句普通的類在JVM里的類型為 包名+類名,也就是全限定名。同一個類型在java語言中和在虛擬機中的表示可能是不一樣的。

Java中數組的繼承關系

上面已經驗證了,數組是對象,也就是說可以以操作對象的方式來操作數組。并且數組在虛擬機中有它特別的類型。既然是對象,遵循Java語言中的規則 -- Object是上帝, 也就是說所有類的頂層父類都是Object。數組的頂層父類也必須是Object,這就說明數組對象可以向上直接轉型到Object,也可以向下強制類型轉換,也可以使用instanceof關鍵字做類型判定。 這一切都和普通對象一樣。如下代碼所示:

?
1
2
3
4
5
6
7
8
9
//1 在test1()中已經測試得到以下結論: 數組也是對象, 數組的頂層父類是Object, 所以可以向上轉型
int[] a = new int[8];
Object obj = a ; //數組的父類也是Object,可以將a向上轉型到Object
//2 那么能向下轉型嗎?
int[] b = (int[])obj; //可以進行向下轉型
//3 能使用instanceof關鍵字判定嗎?
if(obj instanceof int[]){ //可以用instanceof關鍵字進行類型判定
 System.out.println("obj的真實類型是int[]");
}

Java中數組的另一種“繼承”關系

如下代碼是正確的,卻很容易讓我們疑惑:

?
1
2
String[] s = new String[5];
Object[] obja = s; //成立,說明可以用Object[]的引用來接收String[]的對象

Object[]類型的引用可以指向String[]類型的數組對象? 由上文的驗證可以得知數組類型的頂層父類一定是Object,那么上面代碼中s的直接父類是誰呢?難道說String[]繼承自Object[],而Object[]又繼承自Object? 讓我們通過反射的方式來驗證這個問題:

?
1
2
3
//5 那么String[] 的直接父類是Object[] 還是 Object?
System.out.println(s.getClass().getSuperclass().getName());
//打印結果為java.lang.Object,說明String[] 的直接父類是 Object而不是Object[]

由代碼可知,String[]的直接父類就是Object而不是Object[]??墒荗bject[]的引用明明可以指向String[]類型的對象。那么他們的繼承關系有點像這樣:

Java數組的特性_動力節點Java學院整理

這樣的話就違背了Java單繼承的原則。String[]不可能即繼承Object,又繼承Object[]。上面的類圖肯定是錯誤的。那么只能這樣解釋:數組類直接繼承了Object,關于Object[]類型的引用能夠指向String[]類型的對象,這種情況只能是Java語法之中的一個特例,并不是嚴格意義上的繼承。也就是說,String[]不繼承自Object[],但是我可以允許你向上轉型到Object[],這種特性是賦予你的一項特權。

其實這種關系可以這樣表述:如果有兩個類A和B,如果B繼承(extends)了A,那么A[]類型的引用就可以指向B[]類型的對象。如下代碼所示:

?
1
2
3
4
5
6
7
8
9
10
public static class Father {
}
public static class Son extends Father {
}
//6 下面成立嗎? Father是Son的直接父類
Son[] sons = new Son[3];
Father[] fa = sons; //成立
//7 那么Son[] 的直接父類是Father[] 還是 Object[] 或者是Object?
System.out.println(sons.getClass().getSuperclass().getName());
//打印結果為java.lang.Object,說明Son[]的直接父類是Object

上面的結論可以擴展到二維數組和多維數組:

?
1
2
Son[][] sonss = new Son[2][4];
Father[][] fathers = sonss;

上面的代碼可以這樣理解:

將Father[][]數組看成是一維數組, 這是個數組中的元素為Father[],將Son[][]數組看成是一維數組, 這是個數組中的元素為Son[],因為Father[]類型的引用可以指向Son[]類型的對象,所以,根據上面的結論,Father[][]的引用可以指向Son[][]類型的對象。

數組的這種用法不能作用于基本類型數據:

?
1
2
int[] aa = new int[4];
//Object[] objaa = aa; //錯誤的,不能通過編譯

這是錯誤的, 因為int不是引用類型,Object不是int的父類,在這里自動裝箱不起作用。但是這種方式是可以的:

?
1
Object[] objss = {"aaa", 1, 2.5};

這種情況下自動裝箱可以工作,也就是說,Object數組中可以存放任何值,包括基本數據類型。

Java為什么會為數組提供這樣一種語法特性呢?也就是說這種語法有什么作用?編寫過Android中Sqlite數據庫操作程序的同學可能發現過這種現象,用一個Object[]引用接收所有的數組對象,在編譯SQL語句時,為SQL語句中的占位符提供對應的值。

?
1
db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age});

所以這種特性主要是用于方法中參數的傳遞。如果不傳遞數組,而是依次傳遞各個值,會使方法參數列表變得冗長。如果使用具體的數組類型,如String[],那么就限定了類型,失去了靈活性。所以傳遞數組類型是一種比較好的方式。但是如果沒有上面的數組特性(如果有兩個類A和B,如果B繼承(extends)了A,那么A[]類型的引用就可以指向B[]類型的對象),那么數組類型就只能通過Object類型接收,這樣就無法在方法內部訪問或遍歷數組中的各個元素。如下代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private static void test3() {
 String[] a = new String[3];
 doArray(a);
}
private static void doArray(Object[] objs){
}
private static void doArray1(Object obj){
 //不能用Object接收數組,因為這樣無法對數組的元素進行訪問
 // obj[1] //錯誤
 //如果在方法內部對obj轉型到數組,存在類型轉換異常的風險
 // Object[] objs = (Object[]) obj;
}
private static void doArray2(String[] strs){
 //如果適用特定類型的數組,就限制了類型,失去靈活性和通用性
}
private static void doArray3(String name, int age, String id, float account){
 //如果不適用數組而是依次傳遞參數,會使參數列表變得冗長,難以閱讀
}

到此為止,數組的特性就總結完了。上文中加粗的部分為重要結論。下面貼出整個源碼:

源碼

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package com.pansoft.zhangjg.testarray;
public class ArrayTest {
 /**
  * @param args
  */
 public static void main(String[] args) {
  test1();
  test2();
  test3();
 }
 /**
  * 數組具有這種特性:
  * 如果有兩個類A和B,如果B繼承(extends)了A,那么A[]類型的引用就可以指向B[]類型的對象
  * 測試數組的特殊特性對參數傳遞的便利性
  */
 private static void test3() {
  String[] a = new String[3];
  doArray(a);
 }
 private static void doArray(Object[] objs){
 }
 private static void doArray1(Object obj){
  //不能用Object接收數組,因為這樣無法對數組的元素進行訪問
  // obj[1] //錯誤
  //如果在方法內部對obj轉型到數組,存在類型轉換異常的風險
  // Object[] objs = (Object[]) obj;
 }
 private static void doArray2(String[] strs){
  //如果適用特定類型的數組,就限制了類型,失去靈活性和通用性
 }
 private static void doArray3(String name, int age, String id, float account){
  //如果不適用數組而是依次傳遞參數,會使參數列表變得冗長,難以閱讀
 }
 /**
  * 測試數組的集成關系, 并且他的繼承關系是否和數組中元素的類型有關
  */
 private static void test2() {
  //1  在test1()中已經測試得到以下結論: 數組也是對象, 數組的頂層父類是Object, 所以可以向上轉型
  int[] a = new int[8];
  Object obj = a ; //數組的父類也是Object,可以將a向上轉型到Object
  //2  那么能向下轉型嗎?
  int[] b = (int[])obj; //可以進行向下轉型
  //3  能使用instanceof關鍵字判定嗎?
  if(obj instanceof int[]){ //可以用instanceof關鍵字進行類型判定
   System.out.println("obj的真實類型是int[]");
  }
  //4  下面代碼成立嗎?
  String[] s = new String[5];
  Object[] obja = s; //成立,說明可以用Object[]的引用來接收String[]的對象
  //5  那么String[] 的直接父類是Object[] 還是 Object?
  System.out.println(s.getClass().getSuperclass().getName());
  //打印結果為java.lang.Object,說明String[] 的直接父類是 Object而不是Object[]
  //6 下面成立嗎? Father是Son的直接父類
  Son[] sons = new Son[3];
  Father[] fa = sons; //成立
  //7  那么Son[] 的直接父類是Father[] 還是 Object[] 或者是Object?
  System.out.println(sons.getClass().getSuperclass().getName());
  //打印結果為java.lang.Object,說明Son[]的直接父類是Object
  /**
   * 做一下總結, 如果A是B的父類, 那么A[] 類型的引用可以指向 B[]類型的變量
   * 但是B[]的直接父類是Object, 所有數組的父類都是Object
   */
  //8  上面的結論可以擴展到二維數組
  Son[][] sonss = new Son[2][4];
  Father[][] fathers = sonss;
  //將Father[][]數組看成是一維數組, 這是個數組中的元素為Father[]
  //將Son[][]數組看成是一維數組, 這是個數組中的元素為Son[]
  //因為Father[]類型的引用可以指向Son[]類型的對象
  //所以,根據上面的結論,Father[][]的引用可以指向Son[][]類型的對象
  /**
   * 擴展結論:
   * 因為Object是所有引用類型的父類
   * 所以Object[]的引用可以指向任何引用數據類型的數組的對象. 如:
   * Object[] objs = new String[1];
   * Object[] objs = new Son[1];
   *
   */
  //9  下面的代碼成立嗎?
  int[] aa = new int[4];
  //Object[] objaa = aa; //錯誤的,不能通過編譯
  //這是錯誤的, 因為Object不是int的父類,在這里自動裝箱不起作用
  //10 這樣可以嗎?
  Object[] objss = {"aaa", 1, 2.5};//成立
 }
 /**
  * 測試在java語言中,數組是不是對象
  * 如果是對象, 那么他的類型是什么?
  */
 private static void test1() {
  int[] a = new int[4];
  //a.length; //對屬性的引用不能當成語句
  int len = a.length; //數組中保存一個字段, 表示數組的長度
  //以下方法說明數組可以調用方法,java中的數組是對象.這些方法是Object中的方法,所以可以肯定,數組的最頂層父類也是Object
  a.clone();
  a.toString();
  /**
   * java是強類型的語言,一個對象總會有一個特定的類型,例如 Person p = new Person();
   * 對象p(確切的說是引用)的類型是Person類, 這個Person類是我們自己編寫的
   * 那么數組的類型是什么呢? 下面使用反射的方式進行驗證
   */
  int[] a1 = {1, 2, 3, 4};
  System.out.println(a1.getClass().getName());
  //打印出的數組類的名字為[I
  String[] s = new String[2];
  System.out.println(s.getClass().getName());
  //打印出的數組類的名字為 [Ljava.lang.String;
  String[][] ss = new String[2][3];
  System.out.println(ss.getClass().getName());
  //打印出的數組類的名字為 [[Ljava.lang.String;
  /**
   * 所以,數組也是有類型的,只不過這個類型不是有程序員自己定義的類, 也不是jdk里面
   * 的類, 而是虛擬機在運行時專門創建的類
   * 類型的命名規則是:
   *  每一維度用一個[表示;
   *  [后面是數組中元素的類型(包括基本數據類型和引用數據類型)
   *
   * 在java語言層面上,s是數組,也是一個對象,那么他的類型應該是String[],
   * 但是在JVM中,他的類型為[java.lang.String
   *
   * 順便說一句普通的類在JVM里的類型為 包名+類名, 也就是全限定名
   */
 }
 public static class Father {
 }
 public static class Son extends Father {
 }
}

以上所述是小編給大家介紹的Java數組的特性_動力節點Java學院整理,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 四虎影视4hu4虎成人 | 一区二区精品在线视频 | 91成人精品| 黄色在线免费 | 中文字幕在线看 | 欧美高清视频在线观看 | 日韩成人在线视频 | 97久久精品午夜一区二区 | 亚洲电影在线观看 | 亚洲一区自拍 | 成人免费av | 色xxx| 狠狠ri| 久久精品国产一区二区三 | 午夜影院久久 | 亚洲视频中文字幕在线观看 | 久久一二三四 | 欧美一级片毛片免费观看视频 | www.伊人网 | 日韩精品一区二区三区丰满 | 国产成人一区二区啪在线观看 | 国产一区二区精品 | 激情在线视频 | 亚洲一区电影 | 最近日韩中文字幕 | 成人a免费 | 亚洲精选一区 | 午夜国产 | 2015成人永久免费视频 | 中文字幕亚洲二区 | 自拍第1页 | 亚洲字幕成人中文在线观看 | 啊啊啊网站 | 激情五月综合网 | 免费视频一区二区 | 先锋av资源 | 亚洲精品久久久久中文字幕欢迎你 | av网站在线免费观看 | 黄色小视频在线观看 | 精品久久久中文字幕 | 欧美日本在线观看 |