一、類型轉換原則
1. 基礎數據類型轉換規則
基礎數據類型轉換主要在在 賦值、方法調用、算術運算 三種情況下發生。
(1) 賦值和方法調用規則
從低位類型到高位類型自動轉換;從高位類型到低位類型需要強制類型轉換:
- 布爾型和其它基本數據類型之間不能相互轉換;
- byte型可以轉換為short、int、、long、float和double;
- short可轉換為int、long、float和double;
- char可轉換為int、long、float和double;
- int可轉換為long、float和double;
- long可轉換為float和double;
- float可轉換為double;
另外還有是直接數的賦值:先通過直接數判斷其類型,然后基本原則和上面談到的賦值原則基本一致;只是直接數是整數時特殊一點,當在可表示范圍內時,可以直接賦值給 byte short char三種類型;
(2) 算術運算規則
a. 基本就是先轉換為高位數據類型,再參加運算,結果也是最高位的數據類型;
b. byte short char運算會轉換為Int;
- 如操作數之一為double,則另一個操作數先被轉化為double,再參與算術運算。
- 如兩操作數均不為double,當操作數之一為float,則另一操作數先被轉換為float,再參與運算。
- 如兩操作數均不為double或float,當操作數之一為long,、則另一操作數先被轉換為long,再參與算術運算。
- 如兩操作數均不為double、float或long,則兩操作數先被轉換為int,再參與運算。
特殊情況:
- 如采用+=、*=等縮略形式的運算符,系統會自動強制將運算結果轉換為目標變量的類型。
- 當運算符為自動遞增運算符(++)或自動遞減運算符(--)時,如果操作數為byte,short或char類型不發生改變;
2. 引用類型轉換規則
- 基本類型 與 對應包裝類 可自動轉換,這是自動裝箱和折箱的原理;
- 兩個引用類型間轉換:
- 子類能直接轉換為父類 或 接口類型;
- 父類轉換為子類要 強制類型轉換;且在運行時若實際不是對應的對象,會拋出ClassCastException運行時異常;
二、數組與List的互換
1. 數組轉java.util.ArrayList
調用Arrays的asList方法。此方法返回一個按照正確的順序包含此列表中所有元素的數組;返回數組的運行時類型就是指定數組的運行時類型。如果列表能放入指定的數組,則返回放入此列表元素的數組。否則,將根據指定數組的運行時類型和此列表的大小分配一個新的數組。
注:對數組的修改會反映到list中,而且Arrays.asList()返回的不是java.util.ArrayList,而是Arrays的內部類java.util.Arrays.ArrayList,不支持add和remove的操作。想要創建一個真正的 ArrayList類,可以這樣做new ArrayList<String>(Arrays.asList(arr));
2. java.util.ArrayList轉數組
調用ArrayList的toArray方法。此方法返回一個受指定數組支持的固定大小的列表。(對列表的修改不會返回到數組中)。
java.util.List list = new java.util.ArrayList(); list.add("1"); list.add("2"); /** * 錯誤轉換: 這樣寫編譯沒有什么問題,但是運行時會報ClassCastException, * 這是因為Java中允許向上和向下轉型,但是這個轉型是否成功是根據Java虛擬機中這個對象的 * 類型來實現的。Java虛擬機中保存了每個對象的類型。而數組也是一個對象。 * 數組的類型是java.lang.Object。把java.lang.Object轉換成java.lang.String是顯然不可能的事情, * 因為這里是一個向下轉型,而虛擬機只保存了這是一個Object的數組,不能保證數組中的元素是String * 的,所以這個轉型不能成功。數組里面的元素只是元素的引用,不是存儲的具體元素, * 所以數組中元素的類 */ //String[] arr = (String[])list.toArray(); //正確轉換, 而且需要預先申請好數組空間 String[] arr = (String[])list.toArray(new String[list.size()]);
數組轉為Set也是一樣的。
三、List 和 Set互轉
因為List和Set都實現了Collection接口,且addAll(Collection<? extends E> c);方法,因此可以采用addAll()方法將List和Set互相轉換;另外,List和Set也提供了Collection<? extends E> c作為參數的構造函數,因此通常采用構造函數的形式完成互相轉化。
//List轉Set Set<String> set = new HashSet<>(list); System.out.println("set: " + set); //Set轉List List<String> list_1 = new ArrayList<>(set); System.out.println("list_1: " + list_1);
和toArray()一樣,被轉換的List(Set)的修改不會對被轉化后的Set(List)造成影響。