变量和常量在内存中的分配

对于基础类型的变量和常量,变量和引用存储在栈中,常量存储在常量池中。


其实这里很好理解,常量池就是不会变化的量嘛,所以用 fianl修饰的。 String a = "abc"; 本来就是常量,因为Str不能改变嘛,改变都是重新给内存地址。 所以a天然就在常量池里面。

编译器先处理int i1 = 9;首先它会在栈中创建一个变量为i1的引用,然后查找栈中是否有9这个值,如果没找到,就将9存放进来,然后将i1指向9。接着处理int i2 = 9;在创建完i2的引用变量后,因为在栈中已经有9这个值,便将i2直接指向9。这样,就出现了i1与i2同时均指向9的情况。最后i3也指向这个9。


成员变量和局部变量在内存中的分配

 对于成员变量和局部变量:成员变量就是方法外部,类的内部定义的变量;局部变量就是方法或语句块内部定义的变量。局部变量必须初始化。 形式参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量随着方法的消失而消失。 成员变量存储在堆中的对象里面,由垃圾回收器负责回收。


  对于以上这段代码,date为局部变量,i,d,m,y都是形参为局部变量,day,month,year为成员变量。下面分析一下代码执行时候的变化:    

main方法开始执行:int date = 9; date局部变量,基础类型,引用和值都存在栈中。

Test test = new Test();test为对象引用,存在栈中,对象(new Test())存在堆中。 

test.change(date);  i为局部变量,引用和值存在栈中。当方法change执行完成后,i就会从栈中消失。

BirthDate d1= new BirthDate(7,7,1970); d1为对象引用,存在栈中,对象(new BirthDate())存在堆中,其中d,m,y为局部变量存储在栈中,且它们的类型为基础类型,因此它们的数据也存储在栈中。day,month,year为成员变量,它们存储在堆中(new BirthDate()里面)。当BirthDate构造方法执行完之后,d,m,y将从栈中消失。 

main方法执行完之后,date变量,test,d1引用将从栈中消失,new Test(), new BirthDate()将等待垃圾回收。

关键来了

调用了  text.change(date)  ,change方法中改变了  date的值,那在main方法中的date的值,到底变化没有???

答案是 ,没有!!!

此时区分数据类型:基本类型和引用类型

基本类型:值存放在局部变量表中,无论如何修改只会修改当前栈帧的值,不会影响其他栈帧。方法执行结束对方法外不会做任何改变;此时需要改变外层的变量,必须返回主动赋值。

引用数据类型:指针存放在局部变量表中,调用方法的时候,副本引用压栈,赋值仅改变副本的引用但是如果直接改变副本引用的值,修改了引用地址的对象,此时方法以外的引用此地址对象当然被修改。(两个引用,同一个地址,任何修改行为2个引用同时生效)

所以这个东西啊,是需要这样来理解。

你可能感兴趣的:(变量和常量在内存中的分配)