一直在看泛型,一直感觉困惑极多,先问两个问题,
List<Integer> li=new ArrayList<Integer>();
List<Number> ln=new ArrayList<Number>();
ln=li; 
说是编译错误...我想问问
1、为什么会出现错误,java5 是怎么处理 这个的?
2、我们通常的多态实现,如下面代码
class A(){};class a extends A{}
class b extends B{}class c
{
    A aa=new a();//或 aa=new b();
    doMethod()
    {
       aa.xxx();//假设 xxx()是一个类A的方法,a和b都进行了实现
     }    }
要是照 泛型的这个规定,以后这样的代码是不是就不能用了?!!!还有一个就是
List<?> ls=new ArrayList<String>();
ls.add(new String("A"));
编译也会出错,说是 ? 是 通配符 ,不确定里面是什么值,所以不能往里面传入具体值 
这是什么逻辑?不是已经初始化为new ArrayList<String>()了吗?请大牛们指点指点迷津,谢谢!!!!!

解决方案 »

  1.   

    你说如果 Animal a = new Animal();VS Cat c = new Cat();
    a == c么?
    还有你的最后一个问题:
    List<?> l 表示l 可以存放 Object 及其 Object 下面的类,那不是和泛型的性能违背了么?
    泛型的引入是为了让我们在编译的时候能确定存入集合中的类型,所以返回的时候不用因为要“强制类型转换”而失去 Generic 的功能。
    要不你用泛型还有什么意义哈···
      

  2.   


    Java的泛型,做的是“编译时的类型检查”。1、为什么会出现错误,java5 是怎么处理 这个的?即使 类型 B 是 类型A 的子类型,那么 List<B> 和 List<A> 也没什么关系,List<B> 也不是 List<A> 的子类型,两种不同的泛型类型赋值就会报错。
    还有一个就是
    List<?> ls=new ArrayList<String>();
    ls.add(new String("A"));
    编译也会出错,说是 ? 是 通配符 ,不确定里面是什么值,所以不能往里面传入具体值 
    这是什么逻辑?不是已经初始化为new ArrayList<String>()了吗?关键词是“编译”,编译当然会出错,因为 ls 声明的类型是 List<?> , 编译器只能看到声明的类型。
      

  3.   

    List<Integer> li=new ArrayList<Integer>();
    List<Number> ln=new ArrayList<Number>();
    ln=li; li跟ln所容纳的元素类型是不一样的,所以会报错可能你会认为Integer是Number的子类,所以可以将List<Integer>转成List<Number>
    其实是错误的.
      

  4.   

    raistlic对第二个问题的解释,我觉得明白了一些,但是对第一个问题的解释,我还是不很清楚,我总觉得范型的使用会破坏多态性!!!这是我的个人理解....希望大牛们答疑解惑,谢谢
      

  5.   

    List<Integer> li=new ArrayList<Integer>();
    List<Number> ln=new ArrayList<Number>();
    ln=li; 
    说是编译错误...我想问问
    ln和li的类型不一样,泛型就是可以简单理解为不需类型转换,要不你的li取出值时,由于不知是什么类型必须先转换为Integer型。
      

  6.   

    第一个这样不就可以了
    List<Integer> li=new ArrayList<Integer>();
    List<? extends Number> ln=new ArrayList<Number>();//Number的子类包含Integer类
    ln=li;
    第二个是因为?是通配符,表示object,而你传了一个String类作为成员,当然会报错
      

  7.   

    List<?> ls=new ArrayList<String>();
    ls.add(new String("A"));
    楼主这个ls是?类型的,也就是Object的,哪有.add()这个方法,肯定就报错了。
      

  8.   

    泛型通配符<?>一般用在参数里面吗
      

  9.   


    第一个问题,一个 List<Integer> 类型的对象不能赋值给 List<Number> ln 变量,可以看成是 Java 的泛型规范,如果这条规范被打破的话,泛型的“类型检查”也就出现了漏洞:
    // 如果下面这一句能通过编译的话
    List<Number> ln = new ArrayList<Integer>();// ln 声明的类型是 List<Number> , 那么任何 Number 类型都应该能安全的加进去
    ln.add(Double.valueOf("1.0")); // runtime exception
    泛型变量本身并不继承它们的引用类型的继承关系,这个特性叫做 "invariant",它的反义词是 "covariant",事实上,数组就是 covariant,比如说, String 是 Object 的子类型,所以 String[] 也是 Object[] 的子类型。所以数组并不能提供可靠的编译时类型检查,其类型检查是在运行时完成的,如果出现问题,它抛出一个运行时异常:
    Number[] numbers = new Integer[10];
    numbers[0] = Double.valueOf("1.0"); // runtime exception