List list=new ArrayList();
list.add("a");
list.add(1);
list.add(new Person1());

List<Integer> li;
li=list;
Iterator<Integer> i=li.iterator();
while(i.hasNext()){
 //     System.out.println(i.next().TYPE);
System.out.println(i.next());
}
这样为什么编译和执行都没有错呢? li这个泛型中,规定了内部的数据类型是Integer 为什么把list赋给它却没错呢?list中明明有三种类型啊,而且执行的时候Iterator中也是Integer,a却能输出,那个对象也可以输出?
加上System.out.println(i.next().TYPE);这句后,为什么又会报不能将String专程Integer呢?

解决方案 »

  1.   

    这样为什么编译和执行都没有错呢? li这个泛型中,规定了内部的数据类型是Integer 为什么把list赋给它却没错呢
    这里赋值有警告,但不报错。泛型作用在编译期的,而你在运行期时你只打印了i.next,并没有使用i.next,当你真正使用i.next时就会有问题了,比如 i.next().intValue()。
      

  2.   

    泛型能保障在编译期的类型安全,在运行期会变回Object类。楼主可以看看类型擦除的概念
      

  3.   

    百度搜索的http://www.aqee.net/java-generics-quick-tutorial/
      

  4.   

    li=list;
    赋值当然没有错,li是List的对象,list也是List的对象。这样赋值当然木有问题
    就好像String a = "a"
         String b = "b"
         a=b;这样固然是木有问题的但是你用迭代器进行迭代的时候,就会报类型型换异常
    因为li这个List对象中,你用泛型规定了。里面只能存放Integer整型
    所以遍历第一次,中间是个"a",映射到Integer中去,就好像 Integer one = "a" 这样自然会报错
      

  5.   

    泛型只是在编译期进行类型检查,到了执行期就会有擦除的效果,也就是存进去的东西都变为类型边界,如果没有定义边界就是Object类型,赋值不会出现错误,到取内容的过程中会有类型不符的错误或者异常
      

  6.   

    楼主需要明白这样几个问题,第一个Arraylist的构造方法在帮助文档里可以查到
    ArrayList(Collection<? extends E> c) 
              构造一个包含指定 collection 的元素的列表,这些元素是按照该 collection 的迭代器返回它们的顺序排列的。上面的extends关键字指定了通配符?的上限意思是只要是E的子类都可以符合要求。而上面的所有的对象都是object的子类,故是正确的。但是你上面的程序是不健全的,会有警告的,因为你没有指明泛型适用的类型。用cmd编译的话会有不安全的警告,但是可以执行的