java中的泛型技术,使得对象类型不在是固定的,而是可以作为参数来指定,比较常用的代码如下
List<Integer> ls=new ArrayList<Integer>()
没有泛型时List默认装载的是Object类对象,所以在取出元素的时候需要强制类型转换成为元素本身的类型。
使用泛型技术,事先指定了这个List装载的对象类型就是Integer,所以在取出元素时不需要再进行类型转换。
泛型类:
在声明一个类的时候,添加类型变量作为它的参数,就构成了一个泛型类。一个简单的例子如下。
package array;
class MyValue
{
private T value1;
private Integer value2;
MyValue(T t1,Integer t2){
this.value1=t1;
this.value2=t2;
}
public T getValue1(){
return value1;
}
public Integer getValue2(){
return value2;
}
}
public class genericity {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyValue
mv4=new MyValue
(5,"5");
MyValue mv1=new MyValue("god",5);
MyValue mv2=new MyValue(5,"good");
System.out.println("mv1 value2="+mv1.getValue2());
System.out.println("mv2 value2="+mv2.getValue2());
mv1.getValue2();
mv2.getValue2();
}
}
在创建类对象时,才指定类中两个参数的类型,通过使用泛型类可以使程序有更大的灵活性,成员变量与方法的类型可以在实际调用时再确定,而不必像原来在开发时就确定。
泛型方法:
在方法中也可以带有一个或者多个类型参数,泛型方法可以在普通类和泛型类中定义,一般以静态方法居多。
public static <T>T getLast(T[] a){
return a[a.length-1];
}
这个方法用于返回T类型数组的最后一个元素,而T类型可以在运行的时候再指定。
类型变量的限制:
使用 类型变量 extends 限定类型序列如:
T extends Number&Comparable&Serializable
则类型变量T的类型只能是Number的子类并且要实现Comparable和Serializable接口。这里Integer类型是符合的String类型不符合,所以不能把T指定为String类型。
泛型通配符:
在使用泛型时,如果 A是B的子类,但是G<A>并不能看做G<B>使用,这和继承不同,如果要让一种泛型匹配其他的泛型,可以使用?符号,ArrayList<?>表示可以接受ArrayList<任意具体类型>
ArrayList<String> as=new ArrayList<String>();
ArrayList<?> ao=new ArrayList<Object>();
ao=as; //若使用ArrayList<Object> ao=new ArrayList<Object>();则会报错。
使用泛型通配符需要注意,泛型通配符只能用于引用声明中,不可以使用采用了泛型通配符的
也可以对泛型通配符进行限制 ? extends 类名或者接口名
泛型的擦除:
如果在调用一个声明了泛型参数的类时不给出泛型参数的类型,系统会自动按照一定的规则来设置泛型参数的类型,这就是泛型的擦除。
使用泛型时要注意一些限制这些限制大部分是由自动擦除引起的。
限制有:
类型参数可以指定的类型中不包括基本类型,如 MyValue<int>非法,MyValue<Integer>可以。
不能在静态成员中使用类型变量。
public class Myclass<T>
{
public static T getValue();
}
类型变量实际代表的类型要在类创建的时候才会给出,而静态方法只要类加载就可以调用,所以这一段代码不能通过编译。
数组,不能再数组声明中使用泛型,如下代码不能通过编译:
MyValue <String>[] mv=new MyValue<String>[10];
泛型的 instanceof检查,
mylist instanceof ArrayList<Integer>
mylist instanceof ArrayList<String>
以上两段代码检查结果是一样的,它只对不包括泛型的部分(ArrayList)进行检查。
下面一段是对HashMap按key排序的代码。
Set<String> keySet = map.keySet();
<span style="white-space:pre"> </span>List<String> keylist=new ArrayList<String>();
<span style="white-space:pre"> </span>for(String k:keySet){
<span style="white-space:pre"> </span>keylist.add(k);
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>Collections.sort(keylist);
<span style="white-space:pre"> </span>for(Iterator<String> ite = keylist.iterator(); ite.hasNext();) {
<span style="white-space:pre"> </span> String temp = ite.next();
<span style="white-space:pre"> </span> System.out.println("key-value: "+temp+","+map.get(temp));
<span style="white-space:pre"> </span>}
如果想要按字典的降序排列,则需改写sort方法里面的比较器Comparator:
Collections.sort(keySet, new Comparator() {
public int compare(Object o1, Object o2) {
if(Integer.parseInt(o1.toString())>Integer.parseInt(o2.toString())
return 1;
if(Integer.parseInt(o1.toString())==Integer.parseInt(o2.toString())
return 0;
else
return -1;
}
});