亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中Arrays.asList() 的不可變陷阱

 更新時(shí)間:2025年06月18日 09:15:08   作者:weixin_52318532  
本文主要介紹了Arrays.asList()創(chuàng)建的集合不可變原因,指出其底層數(shù)組為final且未重寫修改方法,導(dǎo)致增刪拋異常,下面就來介紹一下Arrays.asList() 陷阱,感興趣的可以了解一下

一、問題現(xiàn)象:無法修改的集合

當(dāng)開發(fā)者使用 Arrays.asList() 轉(zhuǎn)換數(shù)組為集合時(shí),嘗試添加/刪除元素會拋出異常:

String[] arr = {"Java", "Python", "Go"};  
List<String> list = Arrays.asList(arr);  

// 嘗試添加元素  
list.add("JavaScript"); // 拋出 UnsupportedOperationException  

// 嘗試刪除元素  
list.remove(0); // 同樣拋出異常  

控制臺報(bào)錯(cuò)

Exception in thread "main" java.lang.UnsupportedOperationException  
	at java.util.AbstractList.add(AbstractList.java:148)  
	at java.util.AbstractList.add(AbstractList.java:108)  

二、原理剖析:為什么不可變?

2.1 源碼分析

// Arrays.java  
public static <T> List<T> asList(T... a) {  
    return new ArrayList<>(a); // 注意:此ArrayList非java.util.ArrayList  
}  

// Arrays內(nèi)部的私有靜態(tài)類  
private static class ArrayList<E> extends AbstractList<E>  
    implements RandomAccess, java.io.Serializable {  
    
    private final E[] a; // final修飾的數(shù)組!  

    ArrayList(E[] array) {  
        a = Objects.requireNonNull(array);  
    }  

    // 未重寫add/remove方法(繼承AbstractList的默認(rèn)實(shí)現(xiàn))  
}  

// AbstractList.java  
public void add(int index, E element) {  
    throw new UnsupportedOperationException();  
}  

2.2 設(shè)計(jì)本質(zhì)

特性Arrays.ArrayListjava.util.ArrayList
存儲結(jié)構(gòu)包裝原始數(shù)組(final)動態(tài)數(shù)組(Object[] elementData)
長度是否可變? 固定長度? 動態(tài)擴(kuò)容
是否支持增刪? 拋出異常? 正常操作
內(nèi)存占用更低(直接引用原數(shù)組)更高(拷貝數(shù)據(jù))

關(guān)鍵限制

  • 底層數(shù)組由 final 修飾,無法擴(kuò)容
  • 未重寫 add()、remove() 等修改方法
  • 繼承 AbstractList 的默認(rèn)實(shí)現(xiàn)(直接拋異常)

三、解決方案:創(chuàng)建真正的可變集合

3.1 使用 new ArrayList() 包裝(推薦)

String[] arr = {"Java", "Python", "Go"};  

// 方案1:構(gòu)造方法包裝  
List<String> mutableList = new ArrayList<>(Arrays.asList(arr));  

// 方案2:Java 8+ Stream API  
List<String> mutableList = Arrays.stream(arr)  
        .collect(Collectors.toList());  

優(yōu)點(diǎn):代碼簡潔,兼容所有Java版本

3.2 Java 9+ 的 List.of() 替代方案

// 不可變集合(Java 9+)  
List<String> immutableList = List.of("Java", "Python", "Go");  

// 需要可變時(shí)顯式轉(zhuǎn)換  
List<String> mutableList = new ArrayList<>(immutableList);  

注意List.of() 創(chuàng)建的集合完全不可變(增刪改均拋異常)

3.3 特殊場景:修改原始數(shù)組

若只需修改元素值(不增刪元素),可操作原始數(shù)組:

String[] arr = {"Java", "Python", "Go"};  
List<String> list = Arrays.asList(arr);  

// 修改元素(允許!)  
list.set(1, "C++");  
System.out.println(Arrays.toString(arr)); // [Java, C++, Go]  

// 原始數(shù)組同步變化  
arr[0] = "Rust";  
System.out.println(list); // [Rust, C++, Go]  

原理:集合直接引用原始數(shù)組,數(shù)據(jù)共享

四、最佳實(shí)踐與總結(jié)

4.1 使用場景決策樹

需要集合操作嗎?  
├── 是 → 需要增刪元素?  
│   ├── 是 → 使用 new ArrayList<>(Arrays.asList(...))  
│   └── 否 → 只需讀/改元素 → Arrays.asList() 或 List.of()  
└── 否 → 直接使用原始數(shù)組  

4.2 各方案特性對比

方法可變性線程安全內(nèi)存開銷Java版本要求
Arrays.asList()部分?非安全1.2+
new ArrayList<>(...)?非安全1.2+
Arrays.stream().collect()?非安全8+
List.of()?安全9+

4.3 終極原則

明確需求:區(qū)分"只讀" vs "可變"場景

優(yōu)先新語法:Java 8+ 項(xiàng)目多用 Stream API

防御式編程

// 返回不可修改視圖(避免誤操作)  
public List<String> getLanguages() {  
    return Collections.unmodifiableList(Arrays.asList("Java", "Python"));  
}  

到此這篇關(guān)于Java中Arrays.asList() 的不可變陷阱的文章就介紹到這了,更多相關(guān)Java Arrays.asList() 陷阱內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Java SpringBoot+vue+實(shí)戰(zhàn)項(xiàng)目詳解

    Java SpringBoot+vue+實(shí)戰(zhàn)項(xiàng)目詳解

    這篇文章主要介紹了SpringBoot+VUE實(shí)現(xiàn)前后端分離的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-09-09
  • SpringBoot整合RabbitMQ實(shí)戰(zhàn)教程附死信交換機(jī)

    SpringBoot整合RabbitMQ實(shí)戰(zhàn)教程附死信交換機(jī)

    這篇文章主要介紹了SpringBoot整合RabbitMQ實(shí)戰(zhàn)附加死信交換機(jī),本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Java StringBuffer類與StringBuilder類用法實(shí)例小結(jié)

    Java StringBuffer類與StringBuilder類用法實(shí)例小結(jié)

    這篇文章主要介紹了Java StringBuffer類與StringBuilder類用法,結(jié)合實(shí)例形式總結(jié)分析了Java StringBuffer類與StringBuilder類的功能、原理及添加、刪除、替換、截取等操作實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2019-03-03
  • JAVASE精密邏輯控制過程詳解(分支和循環(huán)語句)

    JAVASE精密邏輯控制過程詳解(分支和循環(huán)語句)

    在一個(gè)程序執(zhí)行的過程中各條語句的執(zhí)行順序?qū)Τ绦虻慕Y(jié)果是有直接影響的,這篇文章主要給大家介紹了關(guān)于JAVASE精密邏輯控制(分支和循環(huán)語句)的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-04-04
  • @RequestParam?和@RequestBody注解的區(qū)別解析

    @RequestParam?和@RequestBody注解的區(qū)別解析

    在 Spring MVC 中,我們可以使用 @RequestParam 和 @RequestBody 來獲取請求參數(shù),但它們在用法和作用上有一些區(qū)別,這篇文章主要介紹了@RequestParam?和@RequestBody注解的區(qū)別,需要的朋友可以參考下
    2023-06-06
  • Java詳細(xì)分析講解自動裝箱自動拆箱與Integer緩存的使用

    Java詳細(xì)分析講解自動裝箱自動拆箱與Integer緩存的使用

    裝箱就是把基本類型轉(zhuǎn)換成包裝類,拆箱就是把包裝類轉(zhuǎn)換成基本類型,下面這篇文章主要給大家介紹Java中自動裝箱、自動拆箱與Integer緩存,需要的朋友可以參考下
    2022-04-04
  • Linux安裝JDK兩種方式詳細(xì)教程(附圖)

    Linux安裝JDK兩種方式詳細(xì)教程(附圖)

    這篇文章主要給大家介紹了關(guān)于Linux安裝JDK兩種方式詳細(xì)教程的相關(guān)資料,Linux的使用相信大家都要用到j(luò)ava吧,在使用java前我們得先安裝jdk以及配置環(huán)境變量等工作,需要的朋友可以參考下
    2023-11-11
  • Java接口測試Cookie與token原理解析

    Java接口測試Cookie與token原理解析

    這篇文章主要介紹了Java接口測試Cookie與token原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java基礎(chǔ)之Maven詳解

    Java基礎(chǔ)之Maven詳解

    這篇文章主要介紹了Java基礎(chǔ)之Maven詳解,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java排序算法總結(jié)之希爾排序

    Java排序算法總結(jié)之希爾排序

    這篇文章主要介紹了Java排序算法總結(jié)之希爾排序,較為詳細(xì)的分析了希爾排序的原理與java的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05

最新評論