概述
说起类型安全的容器,那么什么是类型不安全的容器呢?容器用来存储数据,常见的存储数据的容器有数组和集合,数组有以下特点:
长度固定
只能存储同一种类型的数据
因为数组只能存储同一种数据类型的数据,那么它就是类型安全的容器,因为集合可以存储任意类型的数据,比如我可以在List中存储一个Apple、一个Orange,但是在取的时候我不知道它们是什么,只知道它们是Object,这样,我以为取出来的是Apple,但是取出来了一个Orange,我又想要用Apple的种子种苹果,但是涨出来发现时橘子。
实例
类型不安全的容器
class Apple{
private static long counter;
private final long id = counter++;
public long id(){
return id;
}
}
class Orange{
}
public class ApplesAndOrangesWithoutGenerics {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
ArrayList apples = new ArrayList();
for(int i = 0; i<3; i++){
apples.add(new Apple());
}
apples.add(new Orange());
for (int i = 0; i<apples.size(); i++)
((Apple)apples.get(i)).id();
}
}
@SuppressWarnings:不受检查的异常,也就是可以抑制警告信息
存储进去三个Apple对象和一个Orangle对象
想取出Orange的id属性
出现运行时异常
ClassCastException: net.sailfishc.holding.Orange cannot be cast to net.sailfishc.holding.Apple
类型安全的容器(泛型)
class Apple{
private static long counter;
private final long id = counter++;
public long id(){
return id;
}
}
class Orange{
}
public class ApplesAndOrangesWithoutGenerics {
public static void main(String[] args) {
ArrayList<Apple> apples = new ArrayList<Apple>();
for(int i = 0; i<3; i++){
apples.add(new Apple());
}
// apples.add(new Orange());
for (int i = 0; i<apples.size(); i++)
apples.get(i).id(); //不用强制转换
}
}
在创建List的时候加入了泛型,使其只能放入Apple
在试图加入Orange的时候会出现编译器异常
在取对象的时候不需要强制转换为Apple,因为编译器已经知道存储的是Apple
向上转型使用泛型
明确指定某个类型作为泛型参数的时候,并不仅限于将该对象放置到容器中,向上转型也可以像其他类型一样作用于泛型。
class GrannySmith extends Apple{}
class Gala extends Apple{}
class Fuji extends Apple{}
class Braeburn extends Apple{}
public class GenericsAndUpcasting {
public static void main(String[] args) {
ArrayList<Apple> apples = new ArrayList<Apple>();
apples.add(new Gala());
apples.add(new GrannySmith());
apples.add(new Fuji());
apples.add(new Braeburn());
for (Apple apple : apples) {
System.out.println(apple);
}
List<Apple> list1 = new ArrayList<Apple>();
List<Apple> list2 = new LinkedList<Apple>();
}
}
-
Apple
GrannySmith
Gala
Fuji
Braeburn
层次结构如上所示,Apple的子类都可以作为集合的元素加入到集合中,并且不会有任何影响。
在实际编码中一般都建议使用类型安全的容器,这样不容易出错,出错也会在编译期间就会展现出来。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。