目录
1.14.1什么是泛型
集合中是可以存放任意对象的,只要把对象存储集合后,那么这时他们都会被提升成Object类型。当我们在取出每一个对象,并且进行相应的操作,这时必须采用类型转换。
public class Generic {
public static void main(String[] args) {
Collection collection = new ArrayList();
//集合没有限定,任何类型都可存放
collection.add("test");
collection.add(23);
Iterator it = collection.iterator();
while(it.hasNext()){
//需要打印每个字符串的长度,就要把迭代出来的对象转成String类型
String str = (String) it.next();
System.out.println(str.length());
}
}
}
但是程序会出现java.lang.ClassCastException ,为什么会这样?
因为collection.add(23);我们存入的是int,根据类型转换兼容,int与String是转型不兼容的,因此会抛出类转换异常。
为了解决这个问题,我们可以使用泛型(Generic) 。
1.14.2泛型的分类
1.14.2.1在类上定义泛型
格式
修饰符 class 类名<代表泛型的变量> {
}
示例
public class Generic <E>{
}
1.14.2.2在方法上定义泛型
格式
修饰符 <代表泛型的变量> 返回值类型 方法名(参数){
}
在调用方法时,传入泛型
在方法定义泛型时,通常将返回值类型与参数列表都使用泛型,这样在方法执行时才会根据参数的类型动态决定泛型的类型
泛型仅仅被声明,没有赋值时会使用object替换
示例
public class Generic {
public <E> void show(E e) {
}
}
1.14.2.3在接口上定义泛型
格式
修饰符 interface接口名<代表泛型的变量> {
}
示例
public interface Generic<E>{
public abstract void f(E e);
public abstract E f2();
}
1.14.3泛型的表示
泛型可以定义在类、接口、方法中,分别表示为泛型类、泛型接口、泛型方法。泛型的使用需要先声明,声明通过<符号>的方式,符号可以任意,编译器通过识别尖括号和尖括号内的字母来解析泛型。泛型的类型只能为类,不能为基本数据类型。尖括号的位置也是固定的,只能在类名之后或方法返回值之前。
一般泛型有约定的符号:E 代表 Element,<E> 通常在集合中使用;T 代表 Type,<T >通常用于表示类;K 代表 Key,V 代表 Value,<K, V> 通常用于键值对的表示;? 代表泛型通配符。
泛型的表达式有如下几种:
- 普通符号 <T>
- 无边界通配符 <?>
- 上界通配符 <? extends E> 父类是 E
- 下界通配符 <? super E> 是 E 的父类
1.14.4泛型通配符
1.14.4.1什么是泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
1.14.4.2泛型通配符的使用
public static void main(String[] args) {
Collection<Intger> list1 = new ArrayList<Integer>();
getElement(list1);
Collection<String> list2 = new ArrayList<String>();
getElement(list2);
}
public static void getElement(Collection<?> coll){}
//?代表可以接收任意类型
泛型不存在继承关系 Collection<Object> list = new ArrayList<String>();这种是错误的。
1.14.4.3受限泛型
1.14.4.3.1泛型上限
只能接收该类型及该类型的子类
类型名称 <? extends 类 > 对象名称
1.14.4.3.2泛型下限
只能接收该类型及该类型的父类型
类型名称 <? super 类 > 对象名称
上一篇:1.13Java-Iterator迭代器、增强for、迭代、递归 |
下一篇: |