《Think in JAVA》:If you are writing code that might be used across more type,thinking about what generic can do.(后面这句话是我自己加的) 。
一、引入泛型的目的:解决安全问题,提高代码重用率
1、安全问题
比如王五创建了一个List集合,想保存一些字符串,但不小心漏写了双引号
List list = new ArrayList();
list.add("张三");
list.add("今年");
list.add(23);
list.add("岁了");
//然而此时程序并没有报错,而是在运行时才出现ClassCastException错误
//因为List集合默认可以存储Object类型,但在运行时,会记住第一次保存的数据类型,之后会强制转换不同的数据类型
安全问题改进版
List<String> list = new ArrayList<String>();
list.add("张三");
list.add("今年");
list.add(23);
list.add("岁了");
//如此,在用户输入类型不一致时,程序就会在运行前提示
2、提高代码重用率
泛型的引入目的之一,就是把类型的确定推迟到调用方法或者创建对象时才去明确其 具体类型,这样提高了代码的重用率,比如,李四写了一个工具类(OutPutType)要给张三使用,但张三需求很多,又要输出String,又要输出int,还得输出boolean。而恰巧李四不懂泛型,为了满足张三的需求,他就必须用方法重载。但,张三又改变需求了,他还要输出double类型,等等。如果还是使用重载,那么李四就得修改工具类。而如果使用泛型类,就可以通过很简约的方式实现张三的需求。
class OutPutType
{
public void show(String a)
{
System.out.println("String类型"+a);
}
public void show(int b)
{
System.out.println("int类型"+b);
}
public void show(boolean c)
{
System.out.println("boolean类型"+c);
}
//........
}
改进版,通过泛型类
class OutPutType<T>
{
private T t;
public Type(T t)
{
this.t = t;
}
public void show()
{
System.out.println(t.getClass().getSimpleName()+"类型:"+t);
}
}
二、泛型的应用:泛型类,泛型方法,泛型接口
1、泛型类
格式:public class 类名<T,E,F....>
作用:可以使类的成员变量,成员方法的类型更加灵活,同时可以通过反射,获得当 前类的类名,方法名,等一些参数
举例:
class OutPutType<T>
{
private T t;
public Type(T t)
{
this.t = t;
}
public void show()
{
System.out.println(t.getClass().getSimpleName()+"类型:"+t);
}
}
2、泛型方法
格式:public<T> 返回类型 方法名(T t)
作用:是的方法的参数可任意指定类型
举例:
class AddElement
{
public<T> void add(T t)
{
System.out.println(t.getClass().getSimpleName()+"类型:"+t);
}
}
//Test
AddElement outPut = new AddElement();
outPut.add("My");
outPut.add("age");
outPut.add("is");
outPut.add(23);
outPut.add("is");
outPut.add(true);
3、泛型接口
格式:public interface 接口名<T ,E ,F......>
作用:和泛型类类似
举例:
interface Inter<T>
{
public abstract void show(T t);
}
class InterElement<T> implements Inter<T>
{
public void show(T t) {
// TODO Auto-generated method stub
}
}
三、泛型通配符
1、任意通配符:<?>
class Demo<T>
{
}
//Test
Demo<Object> demo1 = new Demo<Object>();
Demo<String> demo2 = new Demo<String>();
Demo<Object> demo = new Demo<String>();//cannot convert from Demo<String> to Demo<Object>
//最后一句报错的原因是,Object和String类型不一致
//在使用泛型时,必须前后类型一致
//以下使用通配符解决
Demo<?> demo1 = new Demo<Object>();
Demo<?> demo2 = new Demo<String>();
Demo<?> demo = new Demo<String>();
2、向下限定通配符<? extends E>,指‘?’代表的类型只能是E,或者E的子类,而不能超越E,是一直约束通配符
class Animal<T>
{
}
class Dog extends Animal
{
}
class Cat extends Animal
{
}
//Test
Animal<? extends Animal> an = new Animal<Animal>();
Animal<? extends Animal> anDog = new Animal<Dog>();
Animal<? extends Animal> anCat = new Animal<Cat>();
//而不能是
Animal<? extends Animal> an = new Animal<Object>();
//因为Object不是Animal的子类
3、向上限定通配符<? super E> 表示'?'代表的类型只能是E或者E的父类
class Animal<T>
{
}
class Dog extends Animal
{
}
class Cat extends Animal
{
}
//Test
Animal<? super Animal> anObj = new Animal<Object>();
Animal<? super Dog> anDog = new Animal<Dog>();
Animal<? super Dog> an = new Animal<Animal>();
//而不能是
Animal<? super Dog> anCat = new Animal<Cat>();
//因为Cat不是Dog的父类
四、希望能和大家多多交流,如果有误之处,请留言修正,谢谢!