Java generic function runtime type check
A generic function that stores and reads data is defined in a data persistence process. However, a type conversion error occurs during running and the type does not match. The error location is not the load method, after the load method is called, the List data is obtained, which appears when the list data is used. The element in the result list is actually A type, and the class of B type is passed by calling the load method, but the load is still successful.
I am very confused. After the code debugging is modified, the problem is solved.
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;
/**
* Loading objects from private files
* @ Param context
* @ Param key value (file name)
* @ 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;
}
/**
* Loading object
* @ Param context
* @ Param key value (file name)
* @ Param clazzOfT class type
*/
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;
}
/**
* Load the array list
* @ Param context
* @ Param key value (file name)
* @ Param clazzOfT class type
* @ 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;
}
/**
* Load the array list
* @ Param context
* @ Param key value (file name)
* @ Param clazzOfT class type
* @ 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;
}
The loadArrayList method is incorrect. The loadArrayList2 method below is correct.
Cause Analysis: generic type information is discarded at runtime. erasure can only be used for syntax check during compilation. The initial loadArrayList method only checks the list type and does not check the type of elements in the list. Therefore, it is not rigorous.