美文网首页
Chapter 7 . 泛型

Chapter 7 . 泛型

作者: GeekGray | 来源:发表于2018-10-03 21:20 被阅读1次

    阅读原文

    Chapter 7 . 泛型

    7.1 使用泛型

    1.泛型的声明

    interface List<T> 和 class TestGen<K,V>

    ​其中,T,K,V不代表值,而是表示类型。这里使

    用任意字母都可以。常用T表示,是Type的缩写。

    2.泛型的实例化:

    一定要在类名后面指定类型参数的值(类型)。如:

    List<String> strList = new ArrayList<String>();
    
    Iterator<Customer> iterator = customers.iterator();
    

    T只能是类,不能用基本数据类型填充。


    7.2对于泛型类(含集合类)

    1.对象实例化时不指定泛型,默认为:Object。

    2.泛型不同的引用不能相互赋值。

    3.加入集合中的对象类型必须与指定的泛型类型一致。

    4.静态方法中不能使用类的泛型。

    5.如果泛型类是一个接口或抽象类,则不可创建泛型

    类的对象。

    6.不能在catch中使用泛型

    7.从泛型类派生子类,泛型类型需具体化


    7.3 自定义泛型类

    class Person<T>{
    
    ​         //****使用T****类型定义变量
    
    ​         private T info;
    
    ​         //****使用T****类型定义一般方法
    
    ​         public T getInfo(){
    
    ​                   return info;
    
    ​         }
    
    ​         public void setInfo(T info){
    
    ​                  this.info = info;
    
    ​         }
    

    ****使用T****类型定义构造器**

    public Person(){}
    
    public Person(T info){
    
    ​         **this.info = info;
    
    }
    
    //static****的方法中不能声明泛型
    
    //public static void show(T t){
    
    //}
    
    //不能在try-catch****中使用泛型定义
    
    //try{}
    
    //catch(T t){}            
    
    }
    

    对于泛型方法

    方法,也可以被泛型化,不管此时定义在其中的类是不是泛型化的。在泛型方法中可以定义泛型参数,此时,参数的类型就是传入数据的类型。

    泛型方法的格式:

    [访问权限] <泛型> 返回类型 方法名([泛型标识 参数名称]) 抛出的异常

    public class DAO {
    
    ​         
    
    ​         public <E>  E get(int id, E e){
    
    ​                   
    
    ​                   E result = null;
    
    ​                   
    
    ​                   return result;
    
    ​         }}
    

    7.4 泛型和继承的关系

    如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<B>并不是G<A>的子类型!

    比如:String是Object的子类,但是List<String >并不是List<Object>的子类。

    public void testgenericandsubclass() {
    
    ​         person[] persons = null;
    
    ​         man[] mans = null;
    
    ​         // 而 person[] 是 man[] 的父类.
    
    ​         persons = mans;
    
    ​         person p = mans[0];
    
    ​         // 在泛型的集合上
    
    ​         list<person> personlist = null;
    
    ​         list<man> manlist = null;
    
    ​         // personlist = manlist;(报错)
    
    }
    

    7.5 通配符

    1.使用类型通配符:?

    比如:

    List<?>   ,Map<?,?>
    

    List<?>是List<String>、List<Object>等各种泛型List的父类。

    2.读取List<?>的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。

    3.写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中添加对象。

    Ø 唯一的例外是null,它是所有类型的成员。

    Ø 将任意元素加入到其中不是类型安全的

    Ø Collection<?> c = new ArrayList<String>();

    Ø c.add(new Object()); // 编译时错误

    Ø 因为我们不知道c****的元素类型,我们不能向其中添加对象。

    Ø add方法有类型参数E作为集合的元素类型。我们传给add的任何参数都必须是一个未知类型的子类。因为我们不知道那是什么类型,所以我们无法传任何东西进去。

    Ø 唯一的例外的是null****,它是所有类型的成员。

    Ø 另一方面,我们可以调用get()****方法并使用其返回值。返回值是一个未知的类型,但是我们知道,它总是一个Object


    有限制的通配符

    <?>

    允许所有泛型的引用调用

    举例:

    <? extends Number> (****无穷小 , Number]

    只允许泛型为Number及Number子类的引用调用

    <? super Number> [Number , 无穷大)

    只允许泛型为Number及Number父类的引用调用

    <? extends Comparable>

    只允许泛型为实现Comparable接口的实现类的引用调用

    public static void printCollection3(Collection<? extends Person> coll){
    
    ​         //Iterator只能用Iterator<?>或Iterator<? extends Person>.why?
    
    ​         Iterator<?> iterator  = coll.iterator();
    
    ​         while(iterator.hasNext()){
    
    ​                   System.out.println(iterator.next());
    
    }   }
    
    public static void printCollection4(Collection<? super Person> coll){
    
    ​         Iterator<?> iterator  = coll.iterator();
    
    ​         while(iterator.hasNext()){
    
    ​                   System.out.println(iterator.next());
    
    }   }
    

    泛型应用

    用户在设计类的时候往往会使用类的关联关系,例如,一个人中可以定义一个信息的属性,但是一个人可能有各种各样的信息(如联系方式、基本信息等),所以此信息属性的类型就可以通过泛型进行声明,然后只要设计相应的信息类即可。

    相关文章

      网友评论

          本文标题:Chapter 7 . 泛型

          本文链接:https://www.haomeiwen.com/subject/zgdtaftx.html