黑马程序员技术交流社区

标题: java数组问题 [打印本页]

作者: zhanghuxin    时间: 2013-11-8 09:46
标题: java数组问题
public class ArrayTest2 {

        public static void main(String[] args) {
                //采用静态初始化方式初始化第1个数组
                String[] books=new String[]{
                                "java","Java EE","Ajax","XML"
                };
                //采用静态初始化的简化形式初始化第2个数组
                String[] names={"孙悟空","猪八戒","唐僧"};
                //采用动态初始化的语法初始化第3个数组
                String[] strArr = new String[5];
                //访问3个数组的长度
                System.out.println("第1数组的长度:"+books.length);
                System.out.println("第2数组的长度:"+names.length);
                System.out.println("第3数组的长度:"+strArr.length);
               
                books=names;
                strArr=names;
                System.out.println("----------------------------");
                System.out.println("books数组的长度:"+books.length);
                System.out.println("strArr数组的长度:"+strArr.length);
                books[1]="沙僧";
                System.out.println("names数组的第2个元素是:"+books[1]);
        }
}
请哪个高手能告诉我这个程序中数组的长度会变呢,特别想不通books数组的第二个元素的值会变了,以前的值去哪了?非常感谢了谁能解释一下!
作者: FFF    时间: 2013-11-8 10:19
本帖最后由 FFF 于 2013-11-8 10:27 编辑
  1. System.out.println("第3数组的长度:"+strArr.length);
  2.          
  3.           books=names;
  4.           strArr=names;
  5.           System.out.println("----------------------------");
  6.           System.out.println("books数组的长度:"+books.length);
  7.           System.out.println("strArr数组的长度:"+strArr.length);
  8.           books[1]="沙僧";
复制代码
以上,books=names;你把books的引用指向了names,names正是长度为3的数据。所以books长度会变(StrArr同理)。
然后又对books[1]的元素进行了重新的引用。books[1]="沙僧";所以,books[1]="沙僧"。八戒师兄就被沙师弟给顶替了。books[1]被顶替了。“八戒”无效化,内存就释放了。没有这个“八戒”元素了!

作者: 青年黨衛軍    时间: 2013-11-8 12:47
卤煮,你的代码里呢不是数组的长度变化的问题,而是各个数组地址指针变化的问题。
先说明一下数组初始化的问题:比如语句 String[] a = new String[]{"Hello","World","Yes"};
首先,声明数组引用变量,即String[] a,此时的a并不是一个数组对象,而只是一个相当于指针的变量;
然后,当我们执行new String[]{"Hello","World","Yes"}以后才真正创建了一个数组对象,此时变量a 才指向了堆内存里面的数组对象。
  1.                 String[] books=new String[]{"java","Java EE","Ajax","XML"};
  2.                 String[] names={"孙悟空","猪八戒","唐僧"};
  3.                 String[] strArr = new String[5];
复制代码
在你的代码中,数组books和数组strArr都在内存中的站空间中有了指针变量来指向在内存堆空间中实例化了的对象,且指针变量中的值是实例化后的数组对象在内存堆空间中的数组首地址。所以要明确,books,names,strArr中存放的都是指针地址。但是names数组由于没有进行new操作,所以它的数组数据都是在栈空间中的。通过以下代码你可以查看出三个数组的指针地址是不一样的:
  1. String[] books=new String[]{"java","Java EE","Ajax","XML"};
  2.         System.out.println("booksAdressbefore:"+books);//结果:[Ljava.lang.String;@263c8db9
  3. String[] names={"孙悟空","猪八戒","唐僧"};
  4.         System.out.println("namesAdress:"+names);//结果:[Ljava.lang.String;@517c804b
  5. String[] strArr = new String[5];
  6.         System.out.println("strArrAdressbefore:"+strArr);<span style="line-height: 1.5;">//结果:</span>[Ljava.lang.String;@44cae5b8
复制代码
如果打印数组内容的话呢,此时的三个数组显示的都是各自指针变量指向的地址的内容。当你添加了语句  books=names;   strArr=names;时,相当于你把数组names的指针变量中的地址值赋值给了books和strArr这两个地址指针变量,所以它们都指向了栈内存中的names数组,而它们原来指向的存在于堆内存中的数组是没有改变的,只不过是没有的地址指向,成了暂时的垃圾内存。所以这与不是原来的数组长度变化了,而是指针地址发生了变化。
  1. System.out.println("namesAdress:"+names);//结果:[Ljava.lang.String;@517c804b
  2. books=names;
  3.         System.out.println("booksAdressafter:"+books);//结果:[Ljava.lang.String;@517c804b
  4. strArr=names;
  5.         System.out.println("strArrAdressafter:"+strArr);<span style="line-height: 1.5;">//结果:[Ljava.lang.String;@517c804b</span>
复制代码
通过这几条语句可以证实现在三个数组指针地址都一样,所以它们现在输出的数组内容也肯定是一样的,都是names的数组元素,现在当你修改books数组中的元素时,但books现在指向的是names数组的元素,所以你修改实际上是原来names数组中的元素。


作者: 轩辕迪卡    时间: 2013-11-10 16:27
很有意思的问题啊,数组是什么?数组是一个类啊?数组变量其实就是引用型变量啊,简单的说吧
其实你这里面的books,names和strArr就是类 String[]的三个变量(这么说是不太恰当,不过这样很好理解,事实也确实是这样),那么,你让books = names;很显然,原来的books对应的数组对象变成垃圾了!




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