在一個數據持久化處理中定義了數據保存和讀取的 泛型函數的,可是在運行時出現類型轉換錯誤,類型不匹配,出錯的位置不是load方法,而是在調用load方法以後,獲得了列表數據,對列表數據進行使用時出現的。結果列表裏面的元素實際是A類型,調用load方法傳遞的是B類型的class,可是仍然load成功。java
非常疑惑,最終修改代碼調試後,解決問題。android
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方法只是檢查了列表類型,沒有檢查列表中的元素的類型,因此是不嚴謹的。函數