看下面这段简单的java代码:class Apple{  Apple() { System.out.println("Apple() "); }

  public String toString() {
return ("I have a apple");
  }

}public class Test{
  Apple[] ap = new Apple[2];  {
   for(Apple x : ap)            //foreach循环
     x=new Apple();
 }//  {                           //for循环
//   for(int i=0;i<2;i++)
//      ap[i]=new Apple();
//  }   public static void main(String[] args) {
Test ts = new Test();
for(int i=0; i<2; i++)
  System.out.println(ts.ap[i]);

  }   

其中foreach那一段应该对那个Apple类数组产生两个实例对象,但是在main函数输出中两个输出却都是null,就是空引用。如果将foreach那一段替换为for循环那一段,则确实创建了Apple的两个实例对象,因此输出了两个"I have a apple"。这到底是为什么呢。foreach中x作为ap元素的引用别名,如果它创建了对象,应该ap中的元素指向这两个对象才对,即使x随着foreach循环结束而没有了,怎么到后来数组并没有指向x创建的两个类实例对象呢?疑惑中,请高手解答。我用的jdk版本是1.5的

解决方案 »

  1.   

     for(Apple x : ap)            //foreach循环 
         x=new Apple(); 定义一个变量用于暂存集合中的每一个元素,并执行相应的语句.这里x,不代表ap中的元素,而是这个元素中的每一个元素的副本!以上个人理解,请高手指正!
      

  2.   

    如果x是作为对数组元素中复制的副本,这对于基本类型来说是可以理解的,但是对于类的类型来说,这种复制不大好吧。java中对于类类型一般不都是作为引用传递吗?
      

  3.   

    我想:
       Apple[] ap = new Apple[2];
    定义了一个引用的数组,而不是对像的数组。它的每个元素是指向Apple的一个引用,而非Apple类本身。   for(Apple x : ap)            //foreach循环每次循环做的一件事,就是声明一个指向Apple类的引用x,然后以ap中的元素值为其初始化。这个过程中ap中元素的值并没有改变。以上个人理解,请高手指正!
      

  4.   

    答:Kimi正解!ap中的元素放的就是Applet对象的引用。
      
      

  5.   

    我并不认为foreach循环和for循环有什么本质的区别。
    只是foreach用起来更方便,foreach循环替我们做了for循环中我们普遍要做的事(new一个引用让它指向循环到的对象)
      

  6.   

    foreach()  啊   for()  啊
      

  7.   

    支持lisl2003,不过kimi说得也是这个意思.
      

  8.   

    for循环可以修改循环的集合
    foreach不能修改循环的集合,只能取出来看看,用用~~
      

  9.   

    foreach的个人理解如下:for(Apple x : ap) {
        x = new Apple(); // 请注意下面的对比
    }
    for(int i=0; i<ap.length; i++) {
        Apple x = ap[i];    x = new Apple(); // 对x变量重新赋值(与上面具有相同的含意)
         // ap[i] = x; // foreach应该是少了这一行赋值操作
    }
      

  10.   

    foreach实现迭代器功能
    for(apple x : ap)
    由于你没有实例数组ap里面的x,所以默认是null

    for(int i=0;i <2;i++) 
    ap[i]=new Apple(); 
    把数组ap里面的内容都实例话了,所以就不是null了
      

  11.   

    lisl2003 正解for(Apple x : ap)            //foreach循环 
        x=new Apple(); 
    你把x的引用重新指向了一个对像