浅谈java泛型的类型转换问题
来源:互联网 发布:java程序调用rest api 编辑:程序博客网 时间:2024/06/09 14:59
浅谈java泛型的类型转换问题
- 先引出问题如下:
下面代码编译时<1>处不报错,<2>处报错,为何?
public class Test { public static <T> void printList(List<T> lists) { @SuppressWarnings("unchecked") List<Object> mLists = (List<Object>) lists;//<1>此处为什么不报错? System.out.println(mLists.toString()); } public static void main(String[] args) { List<Object> list_1 = new ArrayList<Object>(); List<String> list_2 = new ArrayList<String>(); list_1.add("Test"); list_1.add(23); list_2.add("zhong"); list_2.add("guo"); list_1 = (List<Object>)list_2; //<2>此处是编译时检查,显然这种类型转换时不被允许的。 printList(list_1); printList(list_2); }}
程序运行结果如下:
我们知道,形如下面的转换在java中是不被允许的:
class A{}class B extends A{}List<B> listB = new ArrayList<B>();List<A> listA = (List<A>)listB; //编译报错
List<B>
是不能转换为List<A>
的,这两种类型看似向上转型合理,其实是没有任何继承关系,理解这点,也就明白刚开始的<2>处为什么编译报错了。那我们现在讨论一下<1>处为什么不报错?
public static <T> void printList(List<T> lists) { @SuppressWarnings("unchecked") List<Object> mLists = (List<Object>) lists;//<1> System.out.println(mLists.toString()); }
我的理解是,调用printList函数时,所涉及到的转型(针对泛型)是一种动态的运行时转型(编译期不做检查,也没法做),而根据java泛型的类型擦除,到时不管List<Object>
中的类型参数是什么都擦除为List<Object>
,所以从这个意义上说,只要是List类型,不管类型参数是什么,理论上都不会报错。下面我们对其进行验证如下:
- List 类型参数为A(
List<A>
)
public class Test { class A{} public static <T> void printList(List<T> lists) { @SuppressWarnings("unchecked") List<A> mLists = (List<A>) lists; //<1> System.out.println(mLists.toString()); } public static void main(String[] args) { List<Object> list_1 = new ArrayList<Object>(); List<String> list_2 = new ArrayList<String>(); list_1.add("Test"); list_1.add(23); list_2.add("zhong"); list_2.add("guo");// list_1 = (List<Object>)list_2; //(1)此处是编译时检查,显然这种类型转换时不被允许的。 printList(list_1); printList(list_2); }}
编译后结果如下:
其中类型A是我们自己定义的内部类型,同样不报错,同样的执行结果。
由此可验证我们的想法。
备注:
刚开始接触java,理解不深,今天看LoaderManager时,看到如下调用,顿感困惑,所以才有这一篇文章,下面我将LoaderManager中令我困惑的地方贴出,以供同仁们参考,有理解不正确的地方望大胆指出。
@SuppressWarnings("unchecked")@SuppressWarnings("unchecked") public <D> Loader<D> initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) { if (mCreatingLoader) { throw new IllegalStateException("Called while creating a loader"); } LoaderInfo info = mLoaders.get(id); if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args); if (info == null) { // Loader doesn't already exist; create. //注意此处callback的类型转换, info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback); if (DEBUG) Log.v(TAG, " Created new loader " + info); } else { if (DEBUG) Log.v(TAG, " Re-using existing loader " + info); info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback; } if (info.mHaveData && mStarted) { // If the loader has already generated its data, report it now. info.callOnLoadFinished(info.mLoader, info.mData); } return (Loader<D>)info.mLoader; }
阅读全文
0 0
- 浅谈java泛型的类型转换问题
- 浅谈void指针的类型转换问题
- Java的类型转换问题
- 浅谈java中类型转换
- 浅谈C++的类型转换
- java类型转换问题
- 关于java类型转换的问题
- 类型转换的问题
- 浅谈C++指针类型的转换
- java 初级类型转换问题
- java中的类型转换问题
- java 中类型转换问题
- java的类型转换
- java的类型转换
- JAVA的类型转换
- java的类型转换
- Java的类型转换
- 浅谈dobuble类型与DateTime类型之间的转换
- mpg123源代码库在Windows 7 编译测试
- unity编辑器拓展七——脚本创建模型
- 这个页面怎么写,求解
- 虚拟局域网VLAN的划分
- 14. java.util.Date
- 浅谈java泛型的类型转换问题
- MyBatis(简介及环境搭建)
- Java基本语法
- 数理统计(二)——切比雪夫不等式、大数定理、伯努利定理、中心极限定理
- css
- 从源代码到Runtime发生的重排序
- C#中 Unicode 字符串转换 iso8859-15 byte数组
- ReactiveObjC 响应函数式框架 简单实用
- Window->Animation