java_泛型

 
泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制。
在jdk1.7之后定义泛型可以不用写后面的<>中的内容
比如:
People<Dog> people = new People<不用写>("李德华", new Dog());
好处
1.将运行时期出现问题ClassCastException,转移到了编译时期。,
    方便于程序员解决问题。让运行时问题减少,安全。,
 
2,避免了强制转换麻烦。
泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,
只要见到<>就要定义泛型。
 
泛型定义有几种方式
1.泛型定义在类上
     作用范围是整个类中,如果类中调用此泛型,就是创建对象是定义的泛型
2.泛型定义在方法上,只在该方法上有用
     定义的名字不同,就不会和类上定义的泛型冲突。
3.静态的方法定义泛型,不能直接用类上的泛型,还没有加载,只能自定义方法的泛型
public class People<P> {
     private String name;
     P pet;
     public People(String name, P pet) {
          this.name = name;
          this.pet = pet;
     }
     public P changePet(P pet) {
          return this.pet=pet;
     }
     public  <T> void method(T t){
          System.out.println(t);
     }
 
     //下面这个方法是错误的,P类型只能通过实例来确定,编译不通过
     /*public static void staticMethod(P p) {
          System.out.println(p);
     }*/
 
     //下面的是正确的,虽然和上面的类型名一样,但是这种方式是自定义了方法的泛型
     //这样是可以正常编译运行的
     public static <P> void staticMethod(P p) {
          System.out.println(p);
     }
     
}
3.泛型定义在接口上
     泛型可以定义在接口上,实现类可以直接指定接口的泛型类型,也可以
     继续定义泛型,其中包括 接口的泛型就可以
     比如:
     Interface a<T>(){}
     class People<T> implements Animal<T>(){}
4.泛型的限定
     ?extend Person 可以定义在任何地方,就是对界限进行限定
     ? super Student
     举例:
     
     ArrayList<? super Pet> arrayList = new ArrayList<>();
          arrayList.add(new Pet());
          arrayList.add(new Cat());
          //下面这句是错误的,编译时期错误,因为存储的实际类型需要在运行时确定,能取出的类型是不能确定的。
          //所以需要是Object类型的
          Pet pet = arrayList.get(0);
 
 
PECS法则
在《effective java》中提出的原则
 
1) 参数写成:T<? super B>,对于这个泛型,?代表容器里的元素类型,由于只规定了元素必须是B的超类,导致元素没有明确统一的“根”(除了Object这个必然的根),所以这个泛型你其实无法使用它,对吧,除了把元素强制转成Object。所以,对把参数写成这样形态的函数,你函数体内,只能对这个泛型做插入操作,而无法读
 
2) 参数写成: T<? extends B>,由于指定了B为所有元素的“根”,你任何时候都可以安全的用B来使用容器里的元素,但是插入有问题,由于供奉B为祖先的子树有很多,不同子树并不兼容,由于实参可能来自于任何一颗子树,所以你的插入很可能破坏函数实参,所以,对这种写法的形参,禁止做插入操作,只做读取
 
 
posted @ 2017-08-28 13:58  赵安之  阅读(160)  评论(0编辑  收藏  举报