一、當把Object數組,強轉的具體的Integer數組時,會報錯。
代碼如下:
//數組強轉報錯演示
Object[] numbers = {1,2,3}; Integer[] ints = (Integer[])numbers;
報錯:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;
原因:
根本原因還是類型的繼承關系問題,Integer[]並不是Object[]的子類。雖然,Integer繼承自Object,但Integer[]的直接父類是Object。即所有數組類型的直接父類都是Object,可以通過反射來驗證。數組類型是寫在jvm里得,就像8種基本類型,我們無法在java的標准庫中找到這個類。
//數組的直接父類演示
@Test public void testArrayClass() { Integer[] i = {1,2,3}; Object[] o = {1,2,3}; System.out.println(o.getClass().getSuperclass().getName()); System.out.println(i.getClass().getSuperclass().getName()); }
輸出結果:
java.lang.Object
java.lang.Object
解決方案,可以對數組每個成員分別轉化:
@Test public void testArrayChange() { Object[] numbers = {1,2,3}; Integer[] ints = new Integer[numbers.length]; for(int i = 0;i<numbers.length;i++) { ints[i] = (Integer)numbers[i]; } }
二、另外:雖然強轉會有類型轉換異常,但是,java有一個語法特性:
當A被B繼承時,A[]類型的引用可以指向B[]類型的實例.
即:A[] a = new B[3]成立。
@Test public void testArrayClass() { Integer[] i = {1,2,3}; Object[] o = i; System.out.println("引用成功!!"); }
控制台:
引用成功!!
這種情況被允許,是java的一個語法特性,這種語法特性的存在是為了方法中參數傳遞的方便。
在給數據庫語句傳遞參數時,將多個參數傳遞給sql語句中的每一個占位符,可以使用Object[]類型的參數來接收,然后,在方法中遍歷數組元素,根據不同類型,轉化成相應的類型數據。
@Test public void testTraversalObject() { Integer[] a = {1,2,3}; String[] b = {"a","b","c"}; traversalArray(a); traversalArray(b); } public void traversalArray(Object[] o) { for(int i = 0;i<o.length;i++) { if(o[i] instanceof Integer) { System.out.println("PreparedStatement添加int參數"); } if(o[i] instanceof String) { System.out.println("PreparedStatement添加String參數"); } if(o[i] instanceof java.util.Date) { System.out.println("PreparedStatement添加String參數"); } else { System.out.println("還有其他類型得意添加!"); } } }
如果沒有這個特性:
1、在方法中定義Object類型的參數,來接收數組參數,如果在代碼內部進行類型轉化,則有類型轉化異常的風險,因為,Object是頂級父類,傳遞的參數可以不是個數組
Object obj = 1;
Object[] objs = (Object[]) obj;
2、使用具體的數據類型數組,String[],Integer[],則會使類型的限制太過固定失去靈活性,每種類型都要新增一個方法來代替。
@Test public void testTraversalObject() { Integer[] a = {1,2,3}; String[] b = {"a","b","c"}; traversalIntegerArray(a); traversalStringArray(b); } public void traversalIntegerArray(Integer[] arr) { for(int i = 0;i<arr.length;i++) { //給PreparedStatement添加參數 } } public void traversalStringArray(String[] arr) { for(int i = 0;i<arr.length;i++) { //給PreparedStatement添加參數 } } }