泛型
没有使用泛型时,只要是对象,不管是什么类型的对象,都可以存储进同一个集合中。使用泛型集合,可以将一个集合中的元素限定为一个特定类型,集合中只能存储同一个类型的对象,这样更安全;并且当从集合获取一个对象时,编译器也可以知道这个对象的类型,不需要对对象进行强制类型转换,这样更方便。
ArrayList<Integer> array1 = new ArrayList<Integer>();
array1.add(1);
array1.add(3);
//泛型是给编译器看的,运行时没有任何泛型的痕迹,可以利用"反射"给集合加入任何类型的值
array1.getClass().getMethod("add", Object.class).invoke(array1, "abc");
System.out.println(array1.get(2));
1、了解泛型
1.1、定义泛型
泛型类
定义:MyValue<T,U>{ //定义两个由类型变量指定类型的成员变量。
private T vlaue1;
private U vlaue2; //定义两个成员方法
public void setValue(T value1,U value2)
{ this.value1=value1;
this.value2=value2;
}
}
使用:MyValue<String,Integer> mv1=new MyValue<String,Integer>();
泛型方法
定义:class FFTest
{
//自定义泛型方法
public static <T> T getLast(T[] a)
{
//返回指定数组的最后一个元素
return a[a.length-1];
}
public static void main(String[] args)
{
//创建字符串类型型的数组。
String[] strs={"第一个元素","第二个元素","第三个元素"};
//使用泛型方法并对其进行指定类型参数
String laststr=FFTest.<String>getLast(strs);
//打印结果
System.out.println("数组strs中的最后一个元素是:"+laststr);
}
1.2、参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>(); //错误!///不写<Object>没错,写了就是明知故犯
Vector<Object> v = new Vector<String>(); //也错误!
1.3、编译器不允许创建泛型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:
Vector<Integer> vectorList[] = new Vector<Integer>[10];
2、泛型中的?通配符
问题:定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据,该方法如何定义呢?
public static void printCollection(Collection<?> collection){
//collection.add("");//?通配符不确定具体参数化类型,不能往collection中增加值
System.out.println(collection.size());
for(Object object:collection){
System.out.println(object);
}
}
用?通使配符可以引用其他各种参数化的类型,?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
3、练习泛型的综合应用
Map<String, Integer> maps = new HashMap<String, Integer>();
maps.put("zxx", 95);
maps.put("lhm", 96);
maps.put("lsd", 97);
/*
* Map.Entry<K, V> 映射项(键-值对)Map.entrySet 方法返回映射的 collection 视图,其中的元素属于此类
* 获得映射项引用的唯一 方法是通过此 collection 视图的迭代器来实现。
*/
Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();//返回此映射中包含的映射关系的 Set 视图
System.out.println("姓名\t成绩\t");
for(Map.Entry<String, Integer> entry:entrySet){
System.out.println(entry.getKey()+"\t"+entry.getValue());
}
4、通过反射获得泛型的参数化类型
System.out.println("---------------获取泛型中参数化类型的实际数据类型---------------------");
Method method = GenericTest.class.getMethod("applyVector", Vector.class);
Type [] types = method.getGenericParameterTypes();
ParameterizedType pType = (ParameterizedType) types[0];
System.out.println(types[0]);
System.out.println(pType.getRawType());//取原始类型
System.out.println(pType.getActualTypeArguments()[0]);//取实际类型
public static void applyVector(Vector<Date> v1){ }
总结
泛型其实就是相当于C++中的模板,对于初学者掌握泛型类、方法、接口的定义及使用即可。听说java泛型很深奥!