一、泛型的出现背景
泛型是变量类型的参数化
注意以下几点:
1、泛型的参数类型只能是引用类型,不能是基本数据类型;
2、可以声明多个泛型参数类型,比如<T, P,Q…>,同时还可以嵌套泛型,例如:<List<String>>;
3、泛型的参数类型可以使用extends语句,例如<T extends superclass>,即该泛型参数的类型是所有实现了superclass的class。
4、泛型的参数类型可以使用super语句,例如< T super childclass>,super是限制泛型参数只能是指定该class的上层父类。
5、泛型还可以使用通配符,例如<? extends ArrayList>,利用此方法可以定义实现了多个ArrayList接口的接口,例如AttributeList,RoleList
java.util.ArrayList javax.management.relation.RoleList
java.util.ArrayList javax.management.AttributeList
public class Demo<? extends ArryList>
{
}
Demo<RoleList> r = new Demo();
Demo<AttributeList> r = new Demo();
首先看一个ArryList数据存储的例子:
import java.io.*;
class FanXingDemo
{
public static void main(String[] args)
{
List list = new ArrayList();
list.add(new File("c:\\1.txt"));
list.add("abc");
Object o = list.get(0);
String s = (String)list.get(1);
System.out.println(o);
System.out.println(s);
}
}
上述代码中String s = (String)list.get(1);进行了强制代码转换,在进行操作之前必须明确List中第index=1的位置存放的是一个String类型的元素,若代码量增多的时候,程序编写会变的复杂,因为不可能去查询List中存储的每一个元素的数据类型。这也是泛型出现的原因。
二、泛型的表示方法
泛型是通过<>标记的,<>里面是类型变量,一般为单个大写字母:
1.变量E,<E>,表示集合的元素类型,例如ArrayList<E>;
2.K和V,<K><V>分别表示表的关键字与值的类型,例如Map.Entry<K, V>;
3.T(有时候用字母U和S),<T>表示“任意类型”,例如,定义的Person类等。
三、泛型的应用场合
在集合中必须使用泛型。
四、泛型通配符(?)
通配符的使用有如下几种方式:
1.<?>,相当于<? extends Object>;
2.<? extends ...>,例如<? extends List>,是指泛型类型为List的子类型;
3.<? super ...>,例如<? extends List>,是指泛型类型为List的父类型;
五、示例
1.用T表示的泛型示例
public class FanXingDemo
{
public static void main(String args[])
{
Per<String> p1 = new Per("a","b");
Per<Integer> p2 = new Per(1,2);
System.out.println(p1.getN()+p1.getA());
System.out.println(p2.getN()+p2.getA());
System.out.println(p1.say());
System.out.println(p2.say());
}
}
class Per<T>
{
private T n;
private T a;
public Per(T n, T a)
{
this.a = a;
this.n = n;
}
public void setN(T n)
{
this.n = n;
}
public T getN()
{
return this.n;
}
public void setA(T a)
{
this.a = a;
}
public T getA()
{
return this.a;
}
public T say()
{
return this.n;
}
}
结果:
ab
3
a
1
分析:从上面可以看出,定义<T>的泛型参数类型,可以按照预想的类型进行实例化,得到想要的结果。
2.用通配符(?)表示的泛型示例
(1)
public class GenericDemo<?>{
}
实例化:GenericDemo<String> str =new GenericDemo<String>();
(2)
public class GenericDemo<? extends List>{
}
实例化:GenericDemo<? extends List> list=null;//一般先赋值为null
list = newGenericDemo<ArrayList>();
list =newGenericDemo<LinkedList>();
(3)
public class GenericDemo<? super List>{
}
实例化:GenericDemo<? super List> list= null;
list = newGenericDemo<Collection>();
注意:
使用<?>或者<? extends Object>的声明方式时,只能通过该名称取得所参考实例的信息,或移除某些信息(赋值为null),不能增加它的信息。
示例:
public class GenericDemo<T>{
private T foo;
public T getFoo()
{
return foo;
}
public void setFoo(T foo)
{
this.foo = foo;
}
} public class GenericMain
{
public static void main(String[] args)
{
GenericDemo<String> str = new GenericDemo<String>();
str.setFoo("Hello World");
//GenericDemo<? extends Object> gd = new GenericDemo<? extends Object>();
GenericDemo<? extends Object> gd = str;//通过该名称取得所参考实例的信息
System.out.println(gd.getFoo());
gd = null;//移除某些信息
System.out.println(gd.getFoo());
//gd = "lpp"; //不能 增加信息,因为不知道gd的具体类型,若想此句编译通过,要把 GenericDemo<? extends Object> gd =str修改成String gd = str
}}