黑马程序员技术交流社区

标题: for增强循环 一点疑问 [打印本页]

作者: wyf880204    时间: 2013-12-27 23:44
标题: for增强循环 一点疑问
import java.util.*;
public class Demo{
        public static void main(String[] args){

                        List li=new ArrayList();
                        li.add(1);
                        li.add(2);
                        li.add(3);
                        for(Integer a : li){
                                System.out.println(a);
                                }
        }
}
这个怎么会编译错误 运行没错啊  for遍历的时候 不能直接 Integer a : li
不应该吧

遍历的是对象 我已经知道 存入的是基本类型封装类 怎么不行啊

作者: 张利星    时间: 2013-12-28 00:15
使用增强for循环读取集合中的元素需要用泛型说明元素类型,这样编译器就会将list内的元素转换为Integer类型来读取而不报错

  1. import java.util.*;
  2. public class Demo{
  3.         public static void main(String[] args){

  4.                         List<Integer> li=new ArrayList<>();  //因为下面程序要读取集合中的元素,所以需要用泛型说明元素类型
  5.                         li.add(1);
  6.                         li.add(2);
  7.                         li.add(3);
  8.                         for(Integer a : li){
  9.                                 System.out.println(a);
  10.                                 }
  11.         }
  12. }
复制代码

作者: Cheers_for_CRAZ    时间: 2013-12-28 00:17
你把集合加上一个泛型<Integer>就可以了,实际上增强for循环遍历集合底层是用Itenter遍历的。用Iterator遍历的时候如果没有泛型,就要用(Integer)it.next()强转,而你用增强for循环的时候没有强转,也不能强转,所以这时候要加上泛型。
作者: 青菜白汤    时间: 2013-12-28 00:29

  1. import java.util.*;
  2. public class Demo{
  3.         public static void main(String[] args){
  4.                         //集合加上泛型<Integer>,以便让你的程序好读取元素
  5.                         List<Integer> li=new ArrayList();
  6.                         li.add(1);
  7.                         li.add(2);
  8.                         li.add(3);
  9.                         for(Integer a : li){
  10.                                 System.out.println(a);
  11.                                 }
  12.         }
  13. }
复制代码

作者: 其LovE斤    时间: 2013-12-28 00:31
因为你没有用泛型限定你集合中要存的是什么类型的数据。

List li=new ArrayList(); //这句你没有说明你要存的是什么类型的,那么就是什么类型的都可以存喽。
li.add(1);   
li.add(2);   //这三句,你是存的int,然后自动装箱了。问题是只有你知道,编译器并不知道
li.add(3);
li.add("a");   //这里我也可以这样存,不会报错。

for(Integer a : li){ //所以这里会报错。不论我上面有没有添加"a"。编译器都不知道li里面到底装的是什么
                            //它会默认的认为,你里面装的是Object。
        System.out.println(a);
     }
   你将你的代码加上泛型  。或者将    for(Integer a : li)里的  integer 改为Object  就没错了。
  在转换成字节码的时候  编译器会有去除泛型参数类型化的操作。但那是运行时,所以你说的运行没错。
但是  在编译时  ,就会报错。编译时和运行时  是不一样的。


作者: 范龙波    时间: 2013-12-28 00:38
你上面的这个代码   List li=new ArrayList(); 这句话 没有指定List集合的具体类型换句话说你什么对象都可以向里面添加,例如 li.add("1"),li.add("abc").当你用for遍历的时候你却用Integer类型去遍历可这时候这个集合,可这个集合不能保证里面装的全是Integer类型.所以编译报错 在定义List<Integer> li = new ArrayList()就好了 或者你在遍历的时候 for(Object a : li)用Object代替Integer 这样也可以.
作者: wyf880204    时间: 2013-12-28 00:43
import java.util.*;
public class Demo{
        public static void main(String[] args){

                         List li =new ArrayList();

                        li.add(1);
                        li.add(2);
                        li.add(3);
       
                        for(int i=Integer(Object obj) : li){
                        //        Integer i=(Integer)obj;
                                System.out.println(i);
                                }
        }
}

怎么不行啊
作者: wyf880204    时间: 2013-12-28 00:53
Cheers_for_CRAZ 发表于 2013-12-28 00:17
你把集合加上一个泛型就可以了,实际上增强for循环遍历集合底层是用Itenter遍历的。用Iterator遍历的时候如 ...

增强for循环 不可以强转么
  1. import java.util.*;
  2. public class Demo{
  3.         public static void main(String[] args){

  4.                          List li =new ArrayList();

  5.                         li.add(1);
  6.                         li.add(2);
  7.                         li.add(3);
  8.        
  9.                         for(int i=Integer(Object obj) : li){
  10.                         //        Integer i=(Integer)obj;
  11.                                 System.out.println(i);
  12.                                 }
  13.         }
  14. }
复制代码
这个可以么

作者: Cheers_for_CRAZ    时间: 2013-12-28 02:20
wyf880204 发表于 2013-12-28 00:53
增强for循环 不可以强转么 这个可以么

首先,你要了解增强for循环的用法for(类型  名称xx:集合或数组){}   名称xx代表的是集合或者数组中的每一个元素,你这句是什么?--》i=Integer(Object obj),强转?i只是代表数组或集合中每一个元素,当遍历的时候,i指的是元素。
如果你想强转,那么这样写—》(integer)i,或者这样写—》(Object)i。这样写还情有可原。但是这样写也是错的,原因有:
首先,集合的底层实现是数组,你相当于遍历的是数组中的元素。那么我就要问了,你遍历的数组是什么类型呀?哦,Integer类型。给我一个能代表数组元素的名称呀,
哦,i。遍历的是哪一个数组呀?哦li。这样我才给你遍历。
但是你如果没有给我加泛型<Integer>,那我怎么知道你要遍历的是什么类型?你只是给我一个集合li,那我怎么给你遍历!
@其LovE斤 的解释也不错,你也可以参考一下他的
作者: wyf880204    时间: 2013-12-28 10:58
Cheers_for_CRAZ 发表于 2013-12-28 02:20
首先,你要了解增强for循环的用法for(类型  名称xx:集合或数组){}   名称xx代表的是集合或者数组中的每 ...

for(int i=Integer(Object obj) : li)
哥们俺的意思是  容器了肯定是对象 所以先将Object obj出来 在将其转为Integer对象封装类型 因为我传的是 123 这样的对象封装类  然后在自动拆箱 成基本数据类型  System.out.println(i); 执行的时候 又执行了一次自动装箱 以字符串输出呢??
作者: 李兴    时间: 2013-12-29 17:17
你不使用泛型的话,List集合add()方法默认添加的时Object类型
可以使用这样的代码
  1. import java.util.*;
  2. public class Demo{
  3.         public static void main(String[] args){

  4.                 List li=new ArrayList();
  5.                 li.add(1);
  6.                 li.add(2);
  7.                 li.add(3);
  8.                 for(Object a : li){
  9.                         System.out.println(a);
  10.                 }
  11.         }
  12. }
复制代码


如果使用泛型那就可以添加指定的类型
代码如下
  1. import java.util.*;
  2. public class Demo{
  3.         public static void main(String[] args){

  4.                 List<Integer> li=new ArrayList<Integer>();
  5.                 li.add(1);
  6.                 li.add(2);
  7.                 li.add(3);
  8.                 for(Integer a : li){
  9.                         System.out.println(a);
  10.                 }
  11.         }
  12. }
复制代码





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