bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

JDK源碼分析(2)之Array相關(guān)-創(chuàng)新互聯(lián)

一、Array 是一個(gè)是對(duì)象嗎?

首先可以肯定的是,數(shù)組是一個(gè)對(duì)象;但是在推導(dǎo)的過(guò)程中還是有些難以理解的問(wèn)題,比如對(duì)于任意一個(gè)引用對(duì)象A,

你所需要的網(wǎng)站建設(shè)服務(wù),我們均能行業(yè)靠前的水平為你提供.標(biāo)準(zhǔn)是產(chǎn)品質(zhì)量的保證,主要從事網(wǎng)站設(shè)計(jì)、做網(wǎng)站、企業(yè)網(wǎng)站建設(shè)、成都做手機(jī)網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)、高端網(wǎng)站設(shè)計(jì)、網(wǎng)頁(yè)制作、做網(wǎng)站、建網(wǎng)站。成都創(chuàng)新互聯(lián)擁有實(shí)力堅(jiān)強(qiáng)的技術(shù)研發(fā)團(tuán)隊(duì)及素養(yǎng)的視覺(jué)設(shè)計(jì)專(zhuān)才。
  • 數(shù)組是協(xié)變的,所以Object[]A[]的父類(lèi),即Object[] o = A[];

  • 數(shù)組是一個(gè)對(duì)象,所以數(shù)組的父類(lèi)是Object,即Object oo = o;

  • 那么A[]Object[]Object是什么關(guān)系呢?

是這樣嗎?
JDK源碼分析(2)之 Array 相關(guān)

我們可以通過(guò)反射來(lái)觀察一下:

private?static?void?test05()?{
??Object[]?o?=?new?String[2];
??System.out.println(o.getClass().getName());
??System.out.println(o.getClass().getSuperclass().getName());
??String[]?s?=?(String[])?o;
??System.out.println(s.getClass().getSuperclass().getName());
??Object?oo?=?s;?
}

打印:
[Ljava.lang.String;
java.lang.Object
java.lang.Object

可以看見(jiàn)A[]Object[]的直接父類(lèi)都是Object,所以他們之間的關(guān)系也一定不是上圖中的多繼承關(guān)系,那么數(shù)組協(xié)變產(chǎn)生的關(guān)系一定不同于extends關(guān)鍵字產(chǎn)生的關(guān)系;

extends關(guān)鍵字產(chǎn)生的繼承關(guān)系是怎么定義呢?
這里我們可以從《Virtual Machine Specifications》中找到答案:

//?ClassFile?結(jié)構(gòu)ClassFile?{
??u4????????????????magic;
??u2????????????????minor_version;
??u2????????????????major_version;
??u2????????????????constant_pool_count;
??cp_info???????????constant_pool[constant_pool_count-1];
??u2????????????????access_flags;
??u2????????????????this_class;
??u2????????????????super_class;
??u2????????????????interfaces_count;
??u2????????????????interfaces[interfaces_count];
??u2????????????????fields_count;
??field_info????????fields[fields_count];
??u2????????????????methods_count;
??method_info???????methods[methods_count];
??u2????????????????attribute_count;
??attributes_info;??attributes[attributes_count];?
}

可以看到extends關(guān)鍵字產(chǎn)生的繼承關(guān)系是記錄在class文件中的super_class里面的。我這里還沒(méi)有在 JDK 源碼里面找到數(shù)組協(xié)變關(guān)系的產(chǎn)生,但是可以猜想這個(gè)應(yīng)該是后來(lái)加的類(lèi)似語(yǔ)法關(guān)系的結(jié)構(gòu)。這里先留著以后看源碼的時(shí)候確認(rèn)吧。

二、Array 的 length 域相關(guān)

在準(zhǔn)備看Array源碼的時(shí)候,我直接就點(diǎn)開(kāi)了java.lang.reflect.Array,后來(lái)才知道這根本不是Array的源碼,看包名就知道,這是使用反射操作數(shù)組的一些方法。Array的class是在運(yùn)行過(guò)程中動(dòng)態(tài)生成的。
那么在Array的class中到底包含了什么呢?在很多的資料中都寫(xiě)了,Array中有類(lèi)似public final int length的成員變量。但是在《Java Language Specifications》10.1. Array Types中明確寫(xiě)了,length不是類(lèi)型的一部分;

  • An array's length is not part of its type.

private?static?void?test06()?{
??String[]?s?=?new?String[2];
??System.out.println(s.length);
??System.out.println(s.getClass().getDeclaredFields().length);??try?{
??System.out.println(s.getClass().getDeclaredField("length"));
??}?catch?(NoSuchFieldException?e)?{
??System.out.println(e.toString());
??}?
}

打印:20java.lang.NoSuchFieldException:?length

可以看到length并不是Array的成員變量,那么length是從哪里來(lái)的呢?
同樣我們可以從ClassFile結(jié)構(gòu)中找打答案;

JDK源碼分析(2)之 Array 相關(guān)

可以看到Arraylength信息是記錄在對(duì)象頭中的,而讀取length信息的時(shí)候,是使用的arraylength字節(jié)碼指令來(lái)讀取的。

三、Array 的創(chuàng)建流程

//?數(shù)組創(chuàng)建的幾種形式String[]?s?=?{"a",?"b",?"c"};??//?初始化器String[]?s1?=?new?String[3];???//?有維度表達(dá)式String[]?s2?=?(String[])?Array.newInstance(String.class,?3);?//?有維度表達(dá)式

數(shù)組創(chuàng)建流程

是否有維度表達(dá)式:
??無(wú):
????創(chuàng)建的時(shí)候每個(gè)元素遞歸深入初始化,失敗則退出
????變量類(lèi)型檢查?->?與數(shù)組類(lèi)型不兼容?->?編譯錯(cuò)誤
????不是可具化類(lèi)型(如:null)?->?編譯錯(cuò)誤?
????空間不足?->?OutOfMemoryError
??有:
????創(chuàng)建的時(shí)候,從左向右地計(jì)算,任意維度表達(dá)式計(jì)算失敗則退出
????檢查所有維度值,有小于0?->?NegativeArraySizeException?
????分配空間,若空間不足?->?OutOfMemoryError
????只有一個(gè)維度表達(dá)式,創(chuàng)建一維數(shù)組,每個(gè)元素初始化化為初始值
????有n個(gè)維度表達(dá)式,執(zhí)行深度為n-1的循環(huán)

四、協(xié)變數(shù)組

1. 逆變與協(xié)變

逆變與協(xié)變用來(lái)描述類(lèi)型轉(zhuǎn)換(type transformation)后的繼承關(guān)系
如果A、B表示類(lèi)型,f(?)表示類(lèi)型轉(zhuǎn)換,≤表示繼承關(guān)系(比如,A≤B表示A是由B派生出來(lái)的子類(lèi))

  • f(?)是逆變的,當(dāng)A≤B時(shí)有f(B)≤f(A)成立;

  • f(?)是協(xié)變的,當(dāng)A≤B時(shí)有f(A)≤f(B)成立;

  • f(?)是不變的,當(dāng)A≤B時(shí)上述兩個(gè)式子均不成立,即f(A)與f(B)相互之間沒(méi)有繼承關(guān)系。

正因?yàn)閿?shù)組是協(xié)變的,所以Object[] o = new A[];

2. 為什么要設(shè)計(jì)為協(xié)變數(shù)組

有種看法認(rèn)為這是在泛型產(chǎn)生之前的妥協(xié)產(chǎn)物,比如在 JDK5 之前還沒(méi)有泛型,但是很多地方需要用泛型來(lái)解決,比如:

//?java.util.Arrayspublic?static?boolean?equals(Object[]?a,?Object[]?a2)?{??if?(a==a2)????return?true;????
??if?(a==null?||?a2==null)????return?false;????
??int?length?=?a.length;??if?(a2.length?!=?length)????return?false;????
??for?(int?i=0;?i<length;?i++)?{
????Object?o1?=?a[i];
????Object?o2?=?a2[i];????if?(!(o1==null???o2==null?:?o1.equals(o2)))??????return?false;
??}??return?true;?
}

最后調(diào)用的是Object.equals()方法,但是不想全部都重寫(xiě)equals,這里最簡(jiǎn)單的就是讓數(shù)組實(shí)現(xiàn)協(xié)變的特性;

3. 為什么不能使用泛型數(shù)組

這里簡(jiǎn)單的講是因?yàn)榉盒褪遣蛔兊模鴶?shù)組是協(xié)變的,所以不能使用泛型數(shù)組;

//?如果泛型也是協(xié)變的private?static?void?test07()?{
??List<Object>?list?=?new?ArrayList<String>();??//?原本會(huì)編譯出錯(cuò)
??list.add(123);
??List<String>?list1?=?list;
??String?s?=?list1.get(0);????//?類(lèi)型錯(cuò)誤}

可以看到如果泛型也是協(xié)變的,那么Collection?在存取數(shù)據(jù)的時(shí)候,就會(huì)產(chǎn)生類(lèi)型轉(zhuǎn)換錯(cuò)誤;

4. 為什么數(shù)組可以是協(xié)變的

private?static?void?test07()?{
??Object[]?o?=?new?String[2];
??o[0]?=?123;
}

運(yùn)行時(shí):
Exception?in?thread?"main"?java.lang.ArrayStoreException:?java.lang.Integer

可以看到數(shù)組,在存數(shù)據(jù)的時(shí)候,還會(huì)檢查數(shù)據(jù)類(lèi)型是否兼容,所以數(shù)組可以是協(xié)變的。

五、數(shù)組在 java 和 c++ 中的區(qū)別

  • C++ 中的數(shù)組只是一個(gè)指針,java 中的數(shù)組是一個(gè)對(duì)象

  • java 中訪問(wèn)數(shù)組會(huì)有額外的范圍檢查

  • java 中會(huì)確保數(shù)組被初始化

六、Array 和 ArrayList的效率對(duì)比

private?static?final?int?SIZE?=?50000;private?static?final?Random?RANDOM?=?new?Random();private?static?void?test_array()?{
??System.out.println("Array:");??long?start?=?System.currentTimeMillis();
??String[]?s?=?new?String[SIZE];??for?(int?i?=?0;?i?<?SIZE;?i++)?{
????s[i]?=?i?+?"";
??}
??
??System.out.println("insert:"?+?(System.currentTimeMillis()?-?start));??
??start?=?System.currentTimeMillis();??for?(int?i?=?0,?len?=?SIZE?*?10;?i?<?len;?i++)?{
????String?ss?=?s[RANDOM.nextInt(SIZE)];
??}
??
??System.out.println("get:"?+?(System.currentTimeMillis()?-?start));
}??
private?static?void?test_list()?{
??System.out.println("ArrayList:");??long?start?=?System.currentTimeMillis();
??List<String>?list?=?new?ArrayList<>(SIZE);??for?(int?i?=?0;?i?<?SIZE;?i++)?{
????list.add(i?+?"");
??}
??
??System.out.println("insert:"?+?(System.currentTimeMillis()?-?start));
??start?=?System.currentTimeMillis();??for?(int?i?=?0,?len?=?SIZE?*?10;?i?<?len;?i++)?{
????String?s?=?list.get(RANDOM.nextInt(SIZE));
??}
??System.out.println("get:"?+?(System.currentTimeMillis()?-?start));
}

打印:
Array:
insert:13get:10ArrayList:
insert:7get:22

對(duì)比可以看到,數(shù)組的插入和隨機(jī)訪問(wèn)效率都要比ArrayList高,但是一般建議優(yōu)先使用列表,只有在優(yōu)先考慮效率的時(shí)候才考慮使用數(shù)組,因?yàn)?/p>

  • 數(shù)組是協(xié)變的不能使用泛型

  • 數(shù)組是具體化的,只有在運(yùn)行時(shí)才知道元素的類(lèi)型

七、總結(jié)

在看數(shù)組的時(shí)候,因?yàn)閏lass是動(dòng)態(tài)創(chuàng)建的,所以看了很久,但是根據(jù)數(shù)組的特性,基本可以認(rèn)為數(shù)組的域和方法,類(lèi)似于:

class?A<T>?implements?Cloneable,?java.io.Serializable?{??public?final?int?length?=?X;??
??public?T[]?clone()?{??try?{????return?(T[])?super.clone();
??}?catch?(CloneNotSupportedException?e)?{????throw?new?InternalError(e.getMessage());
??}
?}
}

創(chuàng)新互聯(lián)www.cdcxhl.cn,專(zhuān)業(yè)提供香港、美國(guó)云服務(wù)器,動(dòng)態(tài)BGP最優(yōu)骨干路由自動(dòng)選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級(jí)流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動(dòng)現(xiàn)已開(kāi)啟,新人活動(dòng)云服務(wù)器買(mǎi)多久送多久。

標(biāo)題名稱(chēng):JDK源碼分析(2)之Array相關(guān)-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://vcdvsql.cn/article44/djpche.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供云服務(wù)器自適應(yīng)網(wǎng)站外貿(mào)建站企業(yè)網(wǎng)站制作網(wǎng)站制作電子商務(wù)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名