新聞中心
一、前言
今天在看阿里Java規(guī)范的時(shí)候看到一條規(guī)范,經(jīng)常使用,卻一直沒(méi)有注意的一條!

為淮北等地區(qū)用戶提供了全套網(wǎng)頁(yè)設(shè)計(jì)制作服務(wù),及淮北網(wǎng)站建設(shè)行業(yè)解決方案。主營(yíng)業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、淮北網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠(chéng)的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會(huì)得到認(rèn)可,從而選擇與我們長(zhǎng)期合作。這樣,我們也可以走得更遠(yuǎn)!
相信大家應(yīng)該踩過(guò)這個(gè)坑,下面來(lái)看一看阿里規(guī)范里的內(nèi)容:
【強(qiáng)制】使用工具類 Arrays.asList() 把數(shù)組轉(zhuǎn)換成集合時(shí),不能使用其修改集合相關(guān)的方法,它的 add / remove / clear 方法會(huì)拋出 UnsupportedOperationException 異常。
『說(shuō)明』:asList 的返回對(duì)象是一個(gè) Arrays 內(nèi)部類,并沒(méi)有實(shí)現(xiàn)集合的修改方法。
Arrays.asList 體現(xiàn)的是適配器模式,只是轉(zhuǎn)換接口,「后臺(tái)的數(shù)據(jù)仍是數(shù)組」。
String[] str = new String[]{ "yang", "guan", "bao" };
List list = Arrays.asList(str);第一種情況:list.add("yangguanbao"); 運(yùn)行時(shí)異常。
第二種情況:str[0] = "change"; list 中的元素也會(huì)隨之修改,反之亦然。
想要最新版Java開(kāi)發(fā)手冊(cè)(黃山版)的可以自行下載一下:
黃山版(2022.2.3發(fā)布)下載鏈接:https://github.com/alibaba/p3c
還請(qǐng)點(diǎn)個(gè)微信公眾號(hào)關(guān)注哈!
下面我們來(lái)從例子和源碼來(lái)詳細(xì)看一下是不是如此!!
二、例子測(cè)試
1、添加元素
String[] arr = {"Hello", "World"};
List stringList = Arrays.asList(arr);
stringList.add("報(bào)錯(cuò)了!");
System.out.println(stringList); 我們看到如文檔所說(shuō),報(bào)了UnsupportedOperationException異常,UnsupportedOperationException是Java編程語(yǔ)言中的一個(gè)異常,它表示不支持當(dāng)前操作或方法。當(dāng)程序嘗試執(zhí)行某個(gè)操作或調(diào)用某個(gè)方法,而該操作或方法不被支持時(shí),就會(huì)拋出此異常。
2、修改數(shù)組
String[] arr = {"Hello", "World"};
List stringList = Arrays.asList(arr);
arr[0] = "修改了呢";
System.out.println(stringList); 我們可以看到,集合隨著數(shù)組的變化而變化!
原因是這樣的:
Arrays.asList()方法返回的集合是基于原始數(shù)組的,也就是說(shuō),它不會(huì)創(chuàng)建一個(gè)新的集合對(duì)象,而是將原始數(shù)組作為集合的底層實(shí)現(xiàn)。因此,當(dāng)您更改原始數(shù)組時(shí),通過(guò)Arrays.asList()方法得到的集合元素也會(huì)隨之改變。
3、提醒
基本數(shù)據(jù)類型要使用包裝類型,不然會(huì)有問(wèn)題!
int[] ints = {1,2};
List ints1 = Arrays.asList(ints);
for (int[] ints2 : ints1) {
System.out.println(ints2);
}
System.out.println(ints1.size()); 我們可以看到集合的數(shù)量為1,這是什么原因呢?
原因是:
由于Java中的泛型不支持基本類型,所以它會(huì)將整個(gè)數(shù)組視為單個(gè)元素添加到列表中。
三、源碼查看究竟
看了一下源碼明明new了一個(gè)ArrayList:
public static List asList(T... a) {
return new ArrayList<>(a);
} 為什么不能操作修改集合呢?
我們?cè)邳c(diǎn)進(jìn)去這個(gè)ArrayList構(gòu)造方法,你會(huì)發(fā)現(xiàn),這個(gè)ArrayList非ArrayList!
是不是有點(diǎn)懵逼,我們先看一下這倆個(gè)的UML圖:
這個(gè)ArrayList是Arrays類的一個(gè)內(nèi)部類,繼承了AbstractList
再看一下源碼:
private static class ArrayList extends AbstractList
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
} 明明有ArrayList為什么還要寫(xiě)一個(gè)內(nèi)部類呢?
主要是為了提高代碼的效率和簡(jiǎn)潔性。由于 Arrays.asList() 返回的 List 對(duì)象是一個(gè)視圖,它只是一個(gè)包裝了原始數(shù)組的列表,并不需要額外的空間來(lái)存儲(chǔ)元素。因此,通過(guò) Arrays.asList() 方法將一個(gè)數(shù)組轉(zhuǎn)換成 List 可以避免創(chuàng)建一個(gè)新的 ArrayList 對(duì)象,從而提高代碼的效率和簡(jiǎn)潔性。
四、總結(jié)
我們從阿里開(kāi)發(fā)手冊(cè)中知道了Arrays.asList()的注意事項(xiàng),自己進(jìn)一步的通過(guò)例子來(lái)進(jìn)行實(shí)踐,最后通過(guò)源碼角度來(lái)知道Arrays.asList()的原理!
我們知道了:
使用工具類 Arrays.asList() 把數(shù)組轉(zhuǎn)換成集合時(shí),不能使用其修改集合相關(guān)的方法,它的 add / remove / clear 方法會(huì)拋出 UnsupportedOperationException 異常。
更改原始數(shù)組時(shí),通過(guò)Arrays.asList()方法得到的集合元素也會(huì)隨之改變。
由于Java中的泛型不支持基本類型,所以它會(huì)將整個(gè)數(shù)組視為單個(gè)元素添加到列表中。
知道 Arrays.asList() 的返回值是ArrayList,它是Arrays類的一個(gè)內(nèi)部類,為了提高代碼的效率和簡(jiǎn)潔性。
以后使用就要注意這些問(wèn)題!
名稱欄目:Arrays.asList()得到的是真的ArrayList?操作修改集合大坑
新聞來(lái)源:http://www.5511xx.com/article/dhcegod.html


咨詢
建站咨詢
