Java泛型函数的运行时类型检查的问题
在一个数据持久化处理中定义了数据保存和读取的 泛型函数的,但是在运行时出现类型转换错误,类型不匹配,出错的位置不是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泛型函数的运行时类型检查的问题的更多相关文章
- Java 泛型优点之编译时类型检查
Java 泛型优点之编译时类型检查 使用泛型代码要比非泛型代码更有优势,下面是 Java 官方教程对泛型其中一个优点的介绍: "Stronger type checks at compile ...
- Java基础之RTTI 运行时类型识别
运行时类型识别(RTTI, Run-Time Type Identification)是Java中非常有用的机制,在Java运行时,RTTI维护类的相关信息. 多态(polymorphism)是基于R ...
- Java泛型类型擦除与运行时类型获取
Java的泛型大家都知道是类型擦除的方式实现的,“编译器会进行泛型擦除”是一个常识了(实际擦除的是参数和自变量的类型).“类型擦除” 并非像许多开发者认为的那样,在 <..> 符号内的东西 ...
- C++学习之显式类型转换与运行时类型识别RTTI
static_cast const_cast reinterpret_cast 运行时类型识别(RTTI) dynamic_cast 哪种情况下dynamic_cast和static_cast使用的情 ...
- C++运行时类型识别
通过运行时类型识别(RTTI),程序能够使用基类的指针或引用来检索这些指针或引用所指对象的实际派生类型. 通过下面两个操作符提供 RTTI: 1. typeid 操作符,返回指针或引用所指对象的实际类 ...
- C++运行时类型判断dynamic_cast和typeid
dynamic_cast dynamic_cast < Type-id > ( expression ) dynamic_cast<类型>(变量) 在运行期间检测类型转换是否安 ...
- Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题
在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...
- java多态的向上转型与向下转型(与编译时类型与运行时类型有关)
1.编译时类型由声明该变量时使用的类型决定,运行时类型由实际赋给该变量的对象决定. 当编译时类型和运行时类型不一致时,就会出现所谓的多态. 因为子类是一个特殊的父类,因此java允许把一个子类对象直接 ...
- RTTI (Run-Time Type Identification,通过运行时类型识别) 转
参考一: RTTI(Run-Time Type Identification,通过运行时类型识别)程序能够使用基类的指针或引用来检查这些指针或引用所指的对象的实际派生类型. RTTI提供了以下两个 ...
随机推荐
- 开源 java CMS - FreeCMS2.2 单位管理
项目地址:http://www.freeteam.cn/ 单位管理 FreeCMS支持多单位同一时候使用,并支持无限树级管理. 1. 加入根单位 从左側管理菜单点击单位管理进入. 点击"加入 ...
- HDU1024 Max Sum Plus Plus 【DP】
Max Sum Plus Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others ...
- springcloud Ribbon自定义负载均衡插件
现在我们通过插件的方式添加新的一种策略. package com.zhuyang.config; import org.springframework.beans.factory.annotation ...
- JavaScript:零星知识
1. 关于document.write() 如果在文档已完成加载后执行 document.write,整个HTML 页面将被覆盖. 2. 对代码行进行折行 您可以在文本字符串中使用反斜杠对代码行进行换 ...
- 批处理学习笔记2 - 编写批处理的for循环
批处理中的for循环集成的功能比较多,可以直接对文件操作. ====================================================================== ...
- 《ZedBoard各种资料网址备份记录》
转载来自于:http://http//www.eefocus.com/crazybingo/blog/2013-02/289101_ab4c8.html 1. Xilinx FPGA相关连接 1) X ...
- LeetCode242——Valid Anagram
Given two strings s and t, write a function to determine if t is an anagram of s. For example, s = & ...
- Java项目(5)——单例模式的应用与研究
单例模式是非常别致的一个模式,非常少有人拿它跟其它模式相比,由于,单例模式非常easy,非常特别,作用就是保证一个类有唯一一个实例,并让一个全局变量使得它能被訪问.而保证这个类仅仅被实例化一次的办法就 ...
- ny220 推桌子
推桌子 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 The famous ACM (Advanced Computer Maker) Company has rent ...
- 在cocos2d-x-3.0 android 平台编译时提示CocosGUI.h: No such file or directory
分类是个让人蛋疼的事情,所幸自己的博客自己做主.这是个高兴的开始. 每天抽空玩2048,终于忍受不住,于是决定自己从网上download下源码,自己编译一个出来.所有的事情都很容易,除了操蛋的中文注释 ...