1.泛型概述
JDK支持的一项新功能,泛型即就是在定义(类定义、方法的定义、成员变量的定义、形式参数的定义等)的时候,指定它为通用类型,也就是说,数据类型可以是任意一个类型
例如:List<?>list=null;
2.使用泛型的主要目的
(1.)努力将运行时异常转换成编译时错误,减少运行时异常的作用(提高了编译器的能力)
(2.)解决了模板编程的问题
下述代码中,普通做法在获取对象时需要类型转换,采用泛型后,就不再需要类型转换
//不用泛型
List list=new ArrayList();
list.add("cyf");
String name=(String)list.get(0);
System.out.println("添加的名字是:"+name);
//采用泛型
List<String> list1=new ArrayList<String>();
list1.add("jby");
String sname=list1.get(0);
System.out.println("添加的名字是:"+sname);
3.泛型的声明
(1.)在定义一个泛型的时候,在<>之间定义形式类型参数
(2.)常见的泛型模型:
*K:键,比如映射的键
*V:值,比如List和Set的内容,或Map中的值
*E:异常类
*T:泛型
4.泛型的使用
(1.)消除类型转换
(2.)自动解包装和自动包装的功能
JDK5.0提供了自动装箱和拆箱的功能,通过这个功能,可以将基本数据类型的数据直接放在容器中,也可以直接从容器中取出基本数据类型
如下示例:
public void text {
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
//自动装箱
list.add(1);
list.add(5);
list.add(8);
list.add(10);
//自动拆箱
for(Integer i:list) {
System.out.println(i);
}
}
}
(3.)限制泛型中类型参数的范围
<?>:允许所有的泛型的引用调用
<?extends Number>:只允许泛型为Number及Number子类的引用调用
<?super Number>:只允许泛型为Number及Number父类的引用调用
<?extends Comparable>:只允许泛型为实现Comparable接口的实现类的引用调用
注意:方法参数中使用集合时不指定泛型,默认为<?>
方法参数中<?extends Number&Comparable>这种修饰符是不支持的
如下示例:
public class text1 {
// 方法参数中使用集合时不指定泛型,默认为<?>
public static void pint(List list) {
for (Object o : list) {
System.out.println(o);
}
}
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("haha");
List<Number> list1 = new ArrayList<Number>();
list1.add(8.8);
List<Integer> list2 = new ArrayList<Integer>();
list2.add(10);
List<Double> list3 = new ArrayList<Double>();
list3.add(5.55);
pint(list); // String类型的泛型对象
pint(list1);// Number类型的泛型对象
pint(list2);// Integer类型的泛型对象
pint(list3);// Double类型的泛型对象
}
}
(4.)泛型方法
在类的定义中添加一个形式类型参数列表,可以将类泛型化;
方法也可以被泛型化,不管它们定义在其中的类是不是泛型化的
a.泛型方法的格式:
修饰符 泛型 返回类型 方法名 参数表 抛出的异常
泛型方法中<?Super Number>这种修饰符是不支持的
b.泛型方法的示例:
Eg:将一个数组的元素转存为List的方法
public class text1 {
// 方法参数中使用集合时不指定泛型,默认为<?>
public static <T> List<T> toList(T[] a) {
List<T> list=new ArrayList<T>();
for(T t:a) { //遍历数组
list.add(t); //数组元素加入到集合中去
}
return list;
}
public static void main(String[] args) {
List<Integer> list1=toList(new Integer[] {5,4,2,6});
System.out.println(list1.size());
List<String> list2=toList(new String[] {"dv","dg","fr"});
System.out.println(list2.size());
}
}
(5.)泛型类
注意:
*带泛型的类不能称为Throwable类和Exception类的子类,不能在catch语句中使用泛型,因为编译时,如果try子句抛出的是已检查异常,编译器无法确定catch语句能不能捕获这个异常
*不能用泛型创建一个对象,如T t=new T();因为泛型可能是一个接口或者抽象类
*静态方法中不能使用类的泛型,因为泛型类中的泛型在创建类时被替换为确定类型。静态方法可以通过类名直接访问,而java为一种强类型语言,没有类型的变量或对象时不允许的,所以静态方法中不能使用类的泛型
再次强调泛型类的创建
public class text3 {
public static void main(String[] args) {
myClass m = new myClass();
myClass<String> m1 = new myClass<String>();
m1.method1("hahaha");
myClass<Integer> m2 = new myClass<Integer>();
m2.method1(123);
}
}
class myClass<T> { // 定义了一个泛型类
public void method1(T t) {
System.out.println(t);
}
public T method2() {
return null;
}
/*
* 静态方法中不能使用类的泛型
public static void m(T t) {
*
* }
*/
/*
* 不能创建泛型类的对象可以是一个接口
public void m(){ T t=new T(); }
*/
/*
* 不能在catch语句中使用泛型
public void m(){ try{ }catch(T t){ } }
*/
}
参考书籍《Java基础与案例开发详解》