A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© dev 中级黑马   /  2012-6-20 15:05  /  2671 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 翁游龙 于 2012-6-21 14:54 编辑

使用Java数组之前一定要初始化数组吗?还有,基本类型数组和引用类型数组之间,
在初始化时的内存分配机制有什么区别吗?对于内存的分配比较模糊,希望高手
详细解释下。谢谢!

评分

参与人数 1技术分 +1 收起 理由
职业规划-刘倩老师 + 1 赞一个!

查看全部评分

9 个回复

倒序浏览
本帖最后由 李天甲 于 2012-6-20 16:39 编辑

您的问题比较抽象
1\使用Java数组之前一定要初始化数组吗? 你可以先声明数组,比如直接int[] s;稍后初始化好了在用
2\基本类型数组和引用类型数组之间,在初始化时的内存分配机制有什么区别吗?
声明java数组的时候,实际上只是产生了一个指向该类型(数组)的引用(它也占用内存空间),
对这个“引用”进行赋值,才将其指向某个内存空间。如果不赋予引用则为null
然后,基本类型数组的初始化是如果不赋值,那么里面是有默认值的.
引用类型的话,如果初始化引用不赋值那里面的初始化值自然就是null了.
回复 使用道具 举报
首先解决数组初始化的问题,数组一定要初始化吗?有些书籍上说使用数组之前必须初始化数组,也就是为数组元素分配内存空间,并指定初始值。但实际上,如果真正掌握了java数组在内存中的分配机制,可以换个方式来初始化数组,或者说,数组无需经过初始化。始终记住,java的数组变量是引用类型的变量,它并不是数组对象本身,只要让数组变量指向有效的数组对象,程序中即可使用该数组变量,举个例子吧:
public class ArrayTest
{
    public static void main(String[] args)
    {
        //定义、并初始化nums数组
        int[] nums = new int[]{3, 5, 20, 12};

        //定义一个prices数组变量
        int[] prices;

        //让prices数组指向nums所引用的数组
        prices = nums;

        for (int i = 0 ; i < prices.length ; i++ )
        {
            System.out.println(prices);
        }

        //将prices数组的第3个元素赋值为34
        prices[2] = 34;

        //访问nums数组的第3个元素,将看到输出34.
        System.out.println("nums数组的第3个元素的值是:" + nums[2]);
    }
}
可以看出程序定义了prices数组之后,并为对prices数组进行初始化,如图1:

档程序执行prices = nums之后prices变量将指向nums变量所引用的数组。其实我们说的使用之前初始化是对数组对象初始化,而不是对数组变量初始化。

再说数组的内存分配

对于基本类型的数组就是在堆内存中分配一个连续的内存空间,未初始化前有默认值


byte shot int long的默认值是0;

float 和double是0.0
char是"\u0000"
boolean 是false
引用类型是null;


对于引用类型的内存分配
也举个例子
public class ReferenceArrayTest
{
    public static void main(String[] args)
    {
        //定义一个students数组变量,其类型是Person[]
        Person[] students;
        //执行动态初始化
        students = new Person[2];
        System.out.println("students所引用的数组的长度是:" + students.length);
        //创建一个Person实例,并将这个Person实例赋给zhang变量
        Person zhang = new Person();
        //为zhang所引用的Person对象的属性赋值
        zhang.age = 15;
        zhang.height = 158;
        //创建一个Person实例,并将这个Person实例赋给lee变量
        Person lee = new Person();
        //为lee所引用的Person对象的属性赋值
        lee.age = 16;
        lee.height = 161;
        //将zhang变量的值赋给第一个数组元素
        students[0] = zhang;
        //将lee变量的值赋给第二个数组元素
        students[1] = lee;
        //下面两行代码的结果完全一样,因为lee和students[1]指向的是同一个Person实例。
        lee.info();
        students[1].info();
    }
内存分配如图2
开始的时候系统为数组分配两个空间默认值是null ,接着new 出两个对象zhang和lee 分别对应着内存中的两块区域。
然后将students[0]赋给zhang,students[1]赋给lee,相当于变量zhang和students[0]指向同一个对象,students[1]和lee也指向同一个对象。


1.png (5.13 KB, 下载次数: 76)

1

1

2.png (10.01 KB, 下载次数: 61)

2.png

评分

参与人数 1技术分 +2 收起 理由
职业规划-刘倩老师 + 2 赞一个!

查看全部评分

回复 使用道具 举报
楼上分析的真是详细,赞!一定向楼上同学学习
回复 使用道具 举报
耿鑫 发表于 2012-6-20 16:33
首先解决数组初始化的问题,数组一定要初始化吗?有些书籍上说使用数组之前必须初始化数组,也就是为数组元 ...

嗯,图画的不错呵呵
回复 使用道具 举报
数组都是引用类型的无论是int[]还是Integer[],既然是应用类型,当然会默认初始化了。
回复 使用道具 举报
数组操作中,在栈内存中保存的永远是数组的名称,只开辟了栈内存空间的数组是永远无法使用的,必须有指向的堆内存才可以使用,要想开辟新的堆内存则必须使用关键字new,然后是将此堆内存的使用权交给了对应的栈内存空间,而且一个堆内存空间可以同时被多个栈内存空间所指向,就像是一个人可以有多个名字,一个具体的人就相当于堆内存,名字就相当于栈内存。
C:\Documents and Settings\Administrator\桌面
回复 使用道具 举报
数组操作中,在栈内存中保存的永远是数组的名称,只开辟了栈内存空间的数组是永远无法使用的,必须有指向的堆内存才可以使用,要想开辟新的堆内存则必须使用关键字new,然后是将此堆内存的使用权交给了对应的栈内存空间,而且一个堆内存空间可以同时被多个栈内存空间所指向,就像是一个人可以有多个名字,一个具体的人就相当于堆内存,名字就相当于栈内存。

1.png (5.75 KB, 下载次数: 71)

1.png

评分

参与人数 1技术分 +1 收起 理由
职业规划-刘倩老师 + 1 赞一个!

查看全部评分

回复 使用道具 举报
dev 中级黑马 2012-6-21 14:49:39
9#
楼上的哥们解释得真周到,图文并茂,大体已经了解了。谢谢吖!
简单说:只要让数组变量指向有效的数组对象,程序中即可使用该数组变量,
不一定每次都要初始化它。
回复 使用道具 举报
dev 中级黑马 2012-6-21 14:49:50
10#
楼上的哥们解释得真周到,图文并茂,大体已经了解了。谢谢吖!
简单说:只要让数组变量指向有效的数组对象,程序中即可使用该数组变量,
不一定每次都要初始化它。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马