Arrays.asList中所遇到的坑


前言

最近在項目上線的時候發現一個問題,從后台報錯日志看:java.lang.UnsupportedOperationException異常
從代碼定位來看,原來是使用了Arrays.asList()方法時把一個數組轉化成List列表時,對得到的List列表進行add()和remove()操作, 所以導致了這個問題。

 

對於這個問題,現在來總結下,當然會總結Arrays下面的一些坑。

源代碼分析

首先,遇到問題不可怕,遇到問題解決就是了,但是必須要保證下次不會再犯相同的問題。
Arrays.asList返回的是同樣的ArrayList,為什么就不能使用add和remove方法呢?

1,查看Arrays.asList 源碼
,

2,查看此ArrayList結構:

3, 在查看AbstractList結構:

果然,UnsupportedOperationException 是這里拋出的,因為Arrays中的ArrayList並沒有實現此方法,故拋出了異常。
所以說 Arrays.asList 返回的 List 是一個不可變長度的列表,此列表不再具備原 List 的很多特性,因此慎用 Arrays.asList 方法。

Arrays中其他坑

1,下面程序輸出是什么?

打印結果是:1
由上面asList 源碼我們可以看到返回的 Arrays 的內部類 ArrayList 構造方法接收的是一個類型為 T 的數組,而基本類型是不能作為泛型參數的,所以這里參數 a 只能接收引用類型,自然為了編譯通過編譯器就把上面的 int[] 數組當做了一個引用參數,所以 size 為 1,要想修改這個問題很簡單,將 int[] 換成 Integer[] 即可。所以原始類型不能作為 Arrays.asList 方法的參數,否則會被當做一個參數。

2,Collections.toArray報錯問題
大家可以看下 java.util.ArrayList 源碼 中特別標記有一句話如下:

Bug地址:https://bugs.java.com/view_bug.do?bug_id=6260652
那下面來試驗下什么情況下會出現這種異常:

如上圖,這種控制台打印的結果如下:
class [Ljava.lang.String;
Exception in thread "main" java.lang.ArrayStoreException: java.lang.Object

我們查看Arrays中ArrayList的toArray源碼:

因為asList返回的是一個String數組,所以這里toArray返回的其實是String[]類型,只不過是這里做了一個向上轉型,將String[]類型轉為Object[]類型罷了。
但是注意,雖然返回的引用為Object[],但實際的類型還是String[],當你往一個引用類型和實際類型不匹配的對象中添加元素時,就是報錯。
具體大家可以參考Java向上轉型和向下轉型的相關知識點。

關於Arrays中的坑就說到這里,有補充的歡迎留言。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM