Java泛型学习
1.0 泛型常用案例
// JDK 1.5 以后出现泛型,若是没有指定泛型可以存任意类型数据,但是注意取值时避免类型转换异常错误
ArrayList list1 = new ArrayList<>();
// JDK 1.5 以后出现泛型,若是指定泛型 <> 只能存指定类型数据
ArrayList<String> list = new ArrayList<>();
// 注意 : 泛型不接受8中基本数据类型,必须申明引用类型
2.0 泛型方法
// 如果单独写泛型方法,需要声明泛型
public <T> void print(List<T> list) {
for (T t : list) {
System.out.println(t);
}
}
//也可以改为传三个参数
public <K, V> void printMap(Map<K, V> map) {
Set<Map.Entry<K, V>> entries = map.entrySet();
for (Map.Entry<K, V> ectriy : entries) {
System.out.println(ectriy.getKey() + "----" + ectriy.getValue());
}
}
// 如果单独写泛型方法,需要声明泛型
public static <T> void println(List<T> list) {
for (T t : list) {
System.out.println(t);
}
}
3.0 泛型类
// 若是将上面两个方法放入类里面,可以把声明的泛型提出来,但是静态方法需要自己定义
// 总结: 静态方法不能通过类定义的泛型,应单独定义泛型
static class ClassText<T> {
// 泛型方法和泛型类
// 如果单独写泛型方法,需要声明泛型
public void print(List<T> list) {
for (T t : list) {
System.out.println(t);
}
}
// 泛型方法和泛型类
// 如果单独写泛型方法,需要声明泛型
public static <F> void println(List<F> list) {
for (F t : list) {
System.out.println(t);
}
}
}
4.0 通配符
- ? 通配符,占位符,标识可以接受未知类型的数据
- <?> 无限定通配符,是让泛型能够接受未知类型的数据
- <? extends E> 有上限的通配符,能接受指定类及其子类类型的数据,E 就是该泛型的上边界。注意:这里不仅限于继承了父类E 的子类,也可代指显现了接口E的类
- <? super E> 有下限的通配符。能接受指定类及其父类类型的数据,E就是该泛型的下边界。注意:你可为一个泛型指定上边界或下边界,但是不能同时指定上下边界
// <?> 无限定通配符,是让泛型能够接受位置类型的数据 :因为不确定传递过来的类型,所以用只能用Object接收
public void print1(List<?> list) {
for (Object t : list) {
System.out.println(t);
}
}
//
class Animal {
String name;
public Animal(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Cat extends Animal {
public Cat(String name) {
super(name);
}
}
// <? extends E> 有上限的通配符,能接受指定类及其子类类型的数据 ===》所以该方法只能遍历Animal及其子类的数据,可以使用Animal 接受,不建议使用Object
public void print2(List<? extends Animal> list) {
for (Animal t : list) {
System.out.println(t);
}
}
// <? super E> 有下限的通配符。===》 所以该方法只能遍历 Cat 类型及Cat 父类类型的集合
// 注意: 在方法内,该集合可以添加Cat类型及其Cat子类的数据,不能添加Animal 数据,因为传递过来的数据可以用animal 接受,但是添加数据那可以添加Cat子类,所以不确定类型,用Object 接收
public void print3(List<? super Cat> list) {
for (Object t : list) {
System.out.println(t);
}
}
5.0 类型擦除
- 泛型只存在于代码编译阶段,编译器编译完带有泛型的java程序后,生成的class文件中与泛型相关的信息会被擦除掉,这个过程叫做类型擦除
public void print4() {
List<String> listStr = new ArrayList<>();
List<Integer> listInt = new ArrayList<>();
// 运行时都是ArrayList 类,泛型都在运行时被擦除了
System.out.println(listStr.getClass() + "--" + listInt.getClass());
}
下一篇 Android 学习(二):Java 反射
网友评论