class BirthDate {
private int day;
private int month;
private int year;
public BirthDate(int d, int m, int y) {
day = d;
month = m;
year = y;
}
public void setDay(int d) {
day = d;
}
public void setMonth(int m) {
month = m;
}
public void setYear(int y) {
year = y;
}
public int getDay() {
return day;
}
public int getMonth() {
return month;
}
public int getYear() {
return year;
}
}
public class Test{
public static void main(String args[]){
Test test = new Test(); //1
int date = 9; //2
BirthDate d1= new BirthDate(7,7,1970); //3
BirthDate d2= new BirthDate(1,1,2000); //4
test.change1(date); //5
test.change2(d1); //6
test.change3(d2); //7
}
public void change1(int i){
i = 1234;
}
public void change2(BirthDate b) {
b = new BirthDate(22,2,2004);
}
public void change3(BirthDate b) {
b.setDay(22);
}
}
根据上面代码,从main方法开始执行,分析代码,序号是代码后面注释的数字:
第一、Test test = new Test();在栈内存空间分配一个局部变量“test”,“test”的值是是一个可以找到new出来的Test的值;在堆内存new出了一个新的Test对象,“test”指向Test对象。
第二、int date = 9;在栈内存里分配一个date变量,它的值是9;
根据以上两行代码,总结:基础类型一块内存,引用类型两块内存
第三、 BirthDate d1= new BirthDate(7,7,1970); 在栈内存分配一个名字叫d1的变量;new对象在堆中分配,调用构造方法的时候,有三个形参,在栈空间里分配3个变量:d,m,y,然后将实参分配给这三个变量:d = 7,m=7,y=1970;最后将d,m,y传给构造方法;方法调用完毕后,所有的局部变量自动消失,所以在栈里d,m,y三个局部变量消失。局部变量d1指向new出来的对象。
第四、 BirthDate d2= new BirthDate(1,1,2000); 同三,不再分析;
第五、test.change1(date); 调用change1()方法,该方法有一个形参,在栈内存分配一个名字叫i的局部变量,将date的值传给i,i=9;最后将i的值变成1234;执行完毕后,局部变量消失,i消失了。内存布局没有任何变化。
第六、test.change2(d1);在栈内存分配一个局部变量b,然后将d1的值将给b(通过d1的值可以找到对应的对象),这样,通过b指向了对应的对象,也可以找到对应的对象;执行完毕,开始执行chage2方法,在change2方法中,又在堆内存中new出一个对象,b指向新new出来的对象。方法调用完毕,局部变量b消失,新new出来的对象等待垃圾收集器回收。
第七、test.change3(d2);在栈中分配一个局部变量b,将d2的值传递给b,b指向d2对应的对象;执行方法,通过b调用setDay()方法,在调用方法的时候,在栈中分配一个局部变量d,然后将22传给d,setDay()调用完成之后d消失,同时change3()也调用完了,b消失;此时d2的值被改变。
关于内存分配的大致图可以链接到这个地址:
http://dl.iteye.com/upload/picture/pic/64638/ac2a02f9-2144-3594-8743-04bcebeea76c.png