標籤:== import arraylist 運行時 ado name list 類型資訊 android
在一個資料持久化處理中定義了資料儲存和讀取的 泛型函數的,但是在運行時出現類型轉換錯誤,類型不符,出錯的位置不是load方法,而是在調用load方法之後,得到了列表資料,對列表資料進行使用時出現的。結果清單裡面的元素實際是A類型,調用load方法傳遞的是B類型的class,但是仍然load成功。
很是疑惑,最終修改代碼調試後,解決問題。
import android.content.Context;import android.text.TextUtils;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.io.ObjectInputStream;import java.util.ArrayList;/** * 從私人檔案載入對象 * @param context * @param key 索引值(檔案名稱) * @return */ public static Object loadFromPrivateFile(Context context, String key) { if (context == null || TextUtils.isEmpty(key)) { return null; } ObjectInputStream objectIn = null; Object result = null; try { FileInputStream fileIn = context.openFileInput(key); objectIn = new ObjectInputStream(fileIn); result = objectIn.readObject(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } finally { if (objectIn != null) { try { objectIn.close(); } catch (IOException e) { } } } return result; } /** * 載入實體物件 * @param context * @param key 索引值(檔案名稱) * @param clazzOfT 類類型 */ public static <T> T loadEntityObject(Context context, String key, Class<T> clazzOfT) { Object object = loadFromPrivateFile(context, key); if (object != null && clazzOfT != null && clazzOfT.isInstance(object)) { return clazzOfT.cast(object); } try { return (T) clazzOfT.newInstance(); } catch (Exception e) { e.printStackTrace(); } return null; } /** * 載入數組列表 * @param context * @param key 索引值(檔案名稱) * @param clazzOfT 類類型 * @return */ @SuppressWarnings("unchecked") public static <T> ArrayList<T> loadArrayList(Context context, String key, Class<T> clazzOfT) { Object object = loadFromPrivateFile(context, key); if (object instanceof ArrayList<?>) { try { return (ArrayList<T>)object; } catch (Exception e) { } } return null; } /** * 載入數組列表 * @param context * @param key 索引值(檔案名稱) * @param clazzOfT 類類型 * @return */ @SuppressWarnings("unchecked") public static <T> ArrayList<T> loadArrayList2(Context context, String key, Class<T> clazzOfT) { ArrayList<T> result = null; Object object = loadEntityObject(context, key, Object.class); if (object instanceof ArrayList<?>) { result = new ArrayList<T>(); ArrayList<?> list = (ArrayList<?>)object; try { final String className = clazzOfT. getName(); for (Object item : list) { if (item. getClass().getName().equals(className)) { result. add((T)item); } } } catch (Exception e) { e.printStackTrace(); } } return result; }
loadArrayList方法是錯誤的實現,下面的loadArrayList2是正確的實現。
原因分析:泛型的類型資訊在運行時是丟棄掉的,準確叫擦除(erasure),只有在編譯時間起到語法檢查的作用。最初的loadArrayList方法只是檢查了清單類型,沒有檢查列表中的元素的類型,所以是不嚴謹的。
Java泛型函數的運行時類型檢查的問題