谁能告诉我关于自定义类 (作为类型)所构造的对象数组在new 时其内存是如何分配的,谢谢!
具体类与问题如下:
//以下是自定义的类
public class Sss {
private int a;
private Sss next;

    public Sss(){
     System.out.println("no parameter constructor is called");
    }
public Sss(int a, Sss next){
this.a = a;
this.next = next;
System.out.println(" parameters constructor is called");
}

public int getA (){
return a;
}

public Sss getNext(){
return next;
}
}
public class Test {

public static void main(String [] args){

Sss [] b = new Sss[5];
for (int i = 0 ; i < 5; i++)
System.out.println(b[i]);

System.out.println("/////////////");

Sss c = new Sss();
System.out.println(c.getA());
System.out.println(c.getNext());
System.out.println("/////////////");
System.out.println(c);

}
}
输出结果如下:
null
null
null
null
null
/////////////
no parameter constructor is called
0
null
/////////////
packageA.Sss@1fb8ee3----------
我不太明白为什么会输出null,对象数组是不是只是根据该对象类型去分配一个(足以放下“引用”)的空间啊,或者说相当于申明一个引用类型,而实际并没有用new到内存堆上开辟出每个Sss的真实空间啊??如果是,按理应该至少会去调用Sss中的一个构造函数吧,但是结果没有哦,谁能来帮我解答下,先谢了。我想进一步知道的是不是基本上没个非基本类型的“引用”所占空间是否一样大,我不是指引用所指向的对象。

解决方案 »

  1.   

    Sss[] b = new Sss[5];
    这条语句确实只是分配了5个引用的空间。而java的所有内存在new之后,都自动是默认值的,对于引用,就自动是null;所以你得到的都是null。我觉得可以这么理解:Sss obj;这条语句只是定义了一个Sss的引用,要获得对象,必须使用obj=new Sss()。相应的,Sss[] b;只是定义了对象(引用)数组的引用,第一次new只是先获得引用数组的空间,然后再用b[i]=new Sss()获取每个对象。在不创建对象的时候,是不会调用构造函数的。
      

  2.   

    对象的数组,必须逐个初始化的
    Sss   []   b   =   new   Sss[5]; 
    for   (int   i   =   0   ;   i   <   5;   i++) 
      b[i] = "";非对象数组,默认值为0
    int[] is = new int[100];
      

  3.   

    LZ你怎么弄的呀,我一个unit不能有两个public class教教我
    是给你空间 了呀,能放五个Sss的空间给你的,可你放什么进去了呀,就像你去开房,开了五间房,但能说明五间房里都有美女等你吗
      

  4.   

    回答Don_Juan 对不起,可能是我没写好,我实际使用的是两个分开的类。不是写在同一个unit中的。据我了解同一个java类中好像只能有一个普遍public的类,简单的修改方式是 去掉其他的类的修饰符 (让其成为无修饰符类)确保java文件中就一个public类即可。我使用的是eclipse ,不知道是不是跟平台有关,具体语法我也没在书上看到过。
      

  5.   

    再问 ltc_mouse 野地芳菲我想问一下Sss   obj;这条语句有没有去开辟一个放下(引用)的空间啊,还有就是每个(引用)它在java中是不是所占的内存空间一样大的,而和其具体的类型无关。诸如String obj1; Sss obj2; 中的obj1 和 obj2 所占的空间一样大????
      

  6.   

    这条语句确实只是分配了5个引用的空间。而java的所有内存在new之后,都自动是默认值的,对于引用,就自动是null;所以你得到的都是null。.....据我个理解,1楼的这句话是有些问题的,其实不能说是分配了引用空间,只能说开辟了5个可以存放此类型的空间(比如一个此类型要占4个字节,则会开辟20字节放在这里),但还没有存入具体的对象而已.也就是说没有new出对象来.而java对于任何非基本类型的初始值都默认为null,基本类型有各自的初始化值的(int 0,double 0.0d,boolean false等).
    而4楼的问题我再说一下:
    一个java源文件只能有一个public的类,这个与平台无关.
      

  7.   

    其实不能说是分配了引用空间,只能说开辟了5个可以存放此类型的空间
    ================================================
    存放此类型的什么东西呢? 我的理解就是存放引用。String obj1; Sss obj2; 这样是在栈上定义了两个引用。不同类型的引用,我认为具有相同的大小,不过也未必,java中我不知道有没什么办法获得类型占用空间的大小。这两篇文档可能有点帮助:
    http://blog.csdn.net/davidweini/archive/2007/12/20/1955871.aspx
    http://blog.csdn.net/kdnuggets/archive/2007/12/04/1916936.aspx
      

  8.   

    这里的关键是对象数组的概念。请记住,对象数组的每一个元素都是一个该对象的引用,而非对象本身。b[i]实际上是b数第i+1个元素的名字,因为这是一个对象数组,而你使用System.out.println(b[i]); 是输出b[i]的值,而b[i]的值实际上是对象的引用,也就是对象的实体空间在JVM上的内存首地址。而现在,你的对象都还没有实际创建(使用new+构造方法),所以,这个地址也不存在,自然只能输出null了。
      

  9.   

    public class Test { public static void main(String[] args) {
    Sss sss=new Sss();
    Sss[] b = new Sss[5];
    b[0]=new Sss();
    b[1]=new Sss();
    b[2]=new Sss(3, sss);
    b[3]=new Sss();
    b[4]=new Sss();
    for (int i = 0; i < 5; i++)
    System.out.println(b[i]); System.out.println("/////////////"); Sss c = new Sss(3, sss);
    System.out.println(c.getA());
    System.out.println(c.getNext());
    System.out.println("/////////////");
    System.out.println(c); }
    }