List泛型相互的转换的一些现象
来源:互联网 发布:网络集成什么意思 编辑:程序博客网 时间:2024/06/15 21:02
List是原生类型,那它可不可以转成List<String> List<?> List<? Extends T> 等等的类型,那么这些类型之间可以怎样转来转去呢,运行过程中却有可能出现什么样的异常,我今天就大胆提出一些自己的观点,欢迎指正
List
List转List<String>
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
{
public static void main(String[] args)
{
List list=new ArrayList();
List<String> list1=new ArrayList<String>();
list.add("回到家还是");
list.add(123);
list.add(12.34);
list1=list; //warnings 类型安全:类型 List 的表达式需要进行未经检查的转换以符合 List<String>
System.out.println(list1.get(1)); //正常输出"回到家还是"
System.out.println(list1.get(0));//出现异常ClassCastException
System.out.println(list1);//此操作不会出现异常,因为toString不涉及泛型
}
}
我应该说的准确一点, list1=list;这一步操作不叫转成,应该叫做:用 List<String> list1的这个引用去操作 List list所指的对象new ArrayList();
解析一下:对象跟应用是两回事,在泛型中 类型检测是由引用来进行的的(不懂的朋友请参考这篇文章)
用 List<String> list1 的这个引用去操作 List list所指的对象new ArrayList()是可以的,
首先、在 List list=new ArrayList(); 这一步中 list所指对象里面存的是Object
其次、 List<String> list1=new ArrayList<String>(); list1=list; 用list1这个引用指向 list所指的那个对
象 new ArrayList()后,这样 new ArrayList()就只能执行更严格的操作,只能往里面存放String类型的数据,所以编译
器允许你这样做。但是很有可能在进行 list1=list 前 new ArrayList()这个对象已经放进了其他类型的数据(8 到10
行),因而在在取出非String类型数据的时候,会出现转换异常
List转List<? extends Number>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
public static void main(String[] args)
{
List list=new ArrayList();
list.add(123);
list.add(33.7);
list.add("cc");
List<? extends Number> list1=list;
Number b=list1.get(2);//运行时出错 ClassCastException
}
}
的 new ArrayList() 的对象执行更严格的操作,所以编译允许这样的操作通过。但是有可能 list1=list;之前的就已经放
了其他非Number的数据,所以在取出数据的时候可能发生ClassCastException异常。
List转List<? super Integer>
Java Code 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class TestList
{
public static void main(String[] args)
{
List list=new ArrayList();
list.add(12.34);
list.add("每一天");
List<? super Integer> listSup=list; //
listSup.add(123);
for (int i = 0; i < list.size(); i++)
{
Object obj = listSup.get(i);
System.out.println(obj);
}
}
}
这种情况跟上面有点特别 listSup = list 之前无论 list所指对象里面放了什么类型的数据,在listSup 指向后,仍能正常的取出数据而不出现ClassCastExcption异常,因为 List<? super Integer> 引用取出的都是Object对象。
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
public static void main(String[] args)
{
List list=new ArrayList();
list.add(12.34);
list.add("每一天");
List<? super Integer> listSup=list; //
listSup.add(123);
for (int i = 0; i < list.size(); i++)
{
Object obj = listSup.get(i);
System.out.println(obj);
}
}
}
List<? extends Type> & List<? super Type>
2
3
4
List<? extends Number> = List<? extends Integer>
List<? super Integer> = List<? super Number>
//语法肯定不对,只是做个比喻
List<? extends Object> 转 List<String>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
public static void main(String[] args)
{
List<? extends Object> list_Exends_Object;
List<? extends String> list_Exends_String;
List<String> list_String = new ArrayList<String>();
list_String=list_Exends_String; //error
//类型不匹配:不能从 List<capture#1-of ? extends String> 转换为 List<String>
list_String=list_Exends_Object; //error
}
}
List<String> list_String 这个引用去操纵一个可能是 Object、String、Number等的对象,List<String> list_String 这个
引用的泛型就表明只能往所指的对象Set 、Get String对象,总不可能往Number对象中放String对象吧。
如果 List<String>List_String = list_Exends_Object;成功,不就意味着可以往 List<? extends Object> list_Exends_Object这个原来所指的对象放入String,
即:
2
3
4
List<? extends Object> list_Exend_Object=list;
List<String> list_String = ist_Exend_Object; // error
因为新的引用是List<String>啊,但是原来的引用 List<? extends Object> list_Exends_Object所指向的具体对象是Number、还是String、或其他的,编译器根本不知
道,因而它不会让你一错再错。
List<? extends Number> 转 List<? extends Integer>
2
3
4
5
6
7
8
9
10
11
12
{
public static void main(String[] args)
{
List<? extends Number> listN=null;
List<? extends Integer> listI=null;
listN=listI;
//listI=listN; 编译不通过,类型不匹配
}
}
理由也很简单如果引用 List<? extends Integer> listI 可以指向 List<? extends Number> listN所指的对象,就有可能出错
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
public static void main(String[] args)
{
List<? extends Number> listN=new ArrayList<Number>();
//listN 指向的是一个 只允许放 Number的 ArrayList
List<? extends Integer> listI=null;
listI=listN; //实际是错误的,在这里假设可行
listI.get(0);
//返回的将是一个Integr
//原来的ArrayList放的是Number
//Number不一定可以转换成Integer
}
}
List<? extends Type> 转 List<? super Type>
List<? extends AnyType> 引用是不能指向 List<? super AnyType> 所指的对象的,反过来也一样,因为 ? super Type 与 ? extends Type 之间总是会有交集的,不存
在谁包含谁的关系。
2
3
4
5
6
7
8
9
10
11
12
13
{
public static void main(String[] args)
{
List<? extends Number> listExt=null;
List<? super Integer> listSup=null;
//listExt=listSup;
//listSup=listExt;
}
}
List<? >等价于 List<? extends Object>
List<? >的情况跟List<? extends Object>一样,以后我会另写文章论述
- List泛型相互的转换的一些现象
- List与数组之间的相互转换
- 【javase】数组与List的相互转换
- map和list 的相互转换
- Set和List之间的相互转换
- List和数组的相互转换
- List与array的相互转换
- 数组和List的相互转换
- Python list和tuple的相互转换
- 【JSON】json与List的相互转换
- 数组与list之间的相互转换
- List与数组之间的相互转换
- 数组与List的相互转换
- Json与List的相互转换
- String[] 与 List 的相互转换
- json与List的相互转换
- 数组与List的相互转换
- List和数组之间的相互转换
- mysql安装问题解决办法
- ios开发property详解
- 文件操作的几个常用方法之一
- 先停下来,看看策划的数值搭建---战斗系统外传
- Java面试题集收藏
- List泛型相互的转换的一些现象
- POJ-3751 时间日期格式转换-24小时制/12小时制
- Activity的生命周期
- iOS 开发 格式化日期时间
- HDU 2046 骨牌铺方格(简单递推)
- poj 3068 有流量限制的最小费用网络流
- Android优化之图片优化
- 求二进制数中1的个数
- 数据库连接池与异步回调