泛型(Generic)
泛型的初步认识:
泛型存在目的:提供给javac编译器使用的,可以限定集合中的输入类型,让编译器挡住源程序中的非法输入。
去类型化:编译器编译带类型说明的集合时会去除掉“类型”信息。
由于有去类型化,我们可以通过反射技术得到集合,再调用它的add方法,来向集合中添加其他类型的数据。
例:向ArrayList<Integer>中添加字符串
import java.lang.reflect.Method;
import java.util.ArrayList;
public class GenericTest
{
public static void main(String[] args) throws Exception
{
ArrayList<Integer> aList = new ArrayList<>();
aList.add(1);
aList.add(2);
System.out.println(aList);
Method addMethod = aList.getClass().getMethod("add", Object.class);
addMethod.invoke(aList, "a");
System.out.println(aList);
}
}
//结果为:
//[1, 2]
//[1, 2, a]
泛型的进阶:
泛型的一些专业术语:
1、整个称为ArrayList<E>泛型类型,其中的E称为类型变量或实际类型参数。
2、ArrayList<Integer>成为参数化的类型,其中Integer成为类型参数的实例或实际类型参数。
3、ArrayList<Integer>读作:ArrayList type type of Integer。
4、ArrayList是原始类型。
泛型的进阶理解:
1、参数化类型与原始类型的兼容性是:
参数化的类型可以引用一个原始类型的对象,编译报告警告;原始类型可以引用一个参数化的类型,编译报告警告。
2、参数化类型不考虑类型参数的继承关系:
ArrayList<Integer> list = new ArrayList<Object>();//错误!!!
ArrayList<Object> list = new ArrayList<Integer> ();//错误!!!
3、编译器不允许创建泛型变量的数组。
ArrayList<Object> list = new ArrayList<Integer> [];//错误!!!
泛型中的通配符 “?”:
1、使用“?”通配符可以引用其他各种参数化的类型,通配符定义的变量主要作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法,因为用“?”就是不确定的类型。
2、通配符扩展:
ArrayList<? extends Number> list = new ArrayList<Integer>();//<? extends Number>代表可以指向Number和他的子类;
ArrayList<? super Integer> list = new ArrayList<Number>();//<? super Integer>代表可以指向Integer和他的父类。
泛型简单应用:
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class GenericTest2
{
public static void main(String[] args)
{
HashMap<String, Integer> hMap = new HashMap<String,Integer>();
hMap.put("zhangsan", 23);
hMap.put("lisi", 24);
hMap.put("wangwu", 21);
Set<Map.Entry<String, Integer>> entrySet = hMap.entrySet();
for(Map.Entry<String, Integer> entry : entrySet)
{
System.out.println(entry.getKey() + ":" + entry.getValue());
}
}
}
//结果为:
//wangwu:21
//lisi:24
//zhangsan:23