黑马程序员技术交流社区

标题: 关于泛型的一点问题 [打印本页]

作者: 王桂丽    时间: 2012-8-29 22:24
标题: 关于泛型的一点问题
1、//原始类型可以引用一个参数化类型的对象
Collection c=new Vector<String>();

2、//参数化类型可以引用一个原始类型的对象
Collection<String>c=new Vector();


疑问
对于1,Vector<String>本来接收String类型,Collections 可以接收任意类型,当然包括String类
Collection c指向Vector我可以理解

但是2,Vector 这种参数化类型装的如果不是String类型呢?为什么可以用参数化的Colletion来接收呢?
作者: 曹操    时间: 2012-8-29 22:34
1、//原始类型可以引用一个参数化类型的对象
Collection c=new Vector<String>();

2、//参数化类型可以引用一个原始类型的对象
Collection<String>c=new Vector();


疑问
对于1,Vector<String>本来接收String类型,Collections 可以接收任意类型,当然包括String类
Collection c指向Vector我可以理解

但是2,Vector 这种参数化类型装的如果不是String类型呢?为什么可以用参数化的Colletion来接收呢?
不是说能代表可以用参数化的Colletion来接收,泛型的好处可以将问题提前到编译时期,也就是说如果装的不是String类型,编译器就会报错
作者: 曹操    时间: 2012-8-29 22:35
再补充点总结
参数化类型不考虑类型参数的继承关系,编译器会报告错误,如:
     Vector<String> v = new Vector<Object>();
     Vector<Object> v1 = new Vector<String>();
   ·在创建数组实例时,数组的元素不能使用参数化类型,编译器会报告错误,如:
     Vector<Integer> v2[] = new Vector<Integer>[10];



泛型中的?通配符
   由于参数化类型不考虑类型参数的继承关系,这时候我们可以使用?通配符,使用?通配符可以引用其他这种参数化类型,?通配符定义的变量主要用作引用。可以调用与参数化无关的方法,不能调用与参数化有关的方法。
   示例:
       public static void printCollection(Collection<?> collection) {
             collection.add("abc");  //错误,因为你给集合添加的是一个String的值,而collection不一定是String
            collection.size();  //调用的是与参数化无关的方法
      }



泛型中的?通配符的扩展
   ·限定通配符的上边界:
     Vector<? extends Number> x = new Vector<Integer>();  //正确
     Vector<? extends Number> x = new Vector<String>();   //错误
   ·限定通配符的下边界:
     Vector<? super Integer> x = new Vector<Number>();  //正确
     Vector<? super Integer> x = new Vector<Byte>();    //错误
   ·提示
     限定通配符总是包括自己
   ·示例
      HashMap<String, Integer> maps = new HashMap<String, Integer>();
      maps.put("zc", 20);
      maps.put("gbb", 30);
  
      Set<Map.Entry<String, Integer>> entrySet = maps.entrySet();
      for(Entry<String, Integer> entry : entrySet) {
             System.out.println(entry.getKey() + ":" + entry.getValue());;
      }



定义泛型方法
   示例:
        public static <T> void swap(T a[],int i,int j) {
              T temp = a;
              a = a[j];
              a[j] = temp;
       }
   
       调用:
        swap(new String[]{"abc","xyz","zc"}, 1, 2); //正确
        swap(new int[]{1,2,3,4},2,3); //错误,只有引用类型才能作为泛型方法的实际参数

   说明:
       ·用于放置泛型的类型参数的尖括号应出现在方法的其他修饰符之后和在方法的返回类型之前。通常类型参数用单个字母的大写字母表示。
       ·只有引用类型才能作为泛型方法的实际参数
       ·在定义泛型的时候可以使用extends限定符,并且可以使用&指定多个边界。
       ·普通方法、构造方法和静态方法中都可以使用泛型。
       ·也可以使用类型变量表示异常,称为参数化的异常,可以用于方法的throws列表中,不能用于catch子句中。如:
         private static <T extends Exception> sayHello() throws T {
                try {
                } catch(Exception e) {  //不能用T
                       throw (T)e
                }
          }
       ·在泛型中可以同时有多个类型参数,用逗号分隔:如:
         public <K,V> getValue(K key){...}


作者: 王桂丽    时间: 2012-8-31 18:10
此问题已解决




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2