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

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


其实这里很好理解,常量池就是不会变化的量嘛,所以用 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个引用同时生效)

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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 此文来源于rj042(仅供学习) Java内存分配与管理是Java的核心技术之一,之前我们曾介绍过Java的内存管...
    自由主义者阅读 2,795评论 0 2
  • 本文将由浅入深详细介绍Java内存分配的原理,以帮助新手更轻松的学习Java。这类文章网上有很多,但大多比较零碎。...
    OSET我要编程阅读 4,400评论 0 1
  • 一:在JAVA中,有六个不同的地方可以存储数据: 1. 寄存器(register)。 这是最快的存储区,因为它位...
    辰321阅读 3,134评论 0 0
  • 结构和联合都是由多个不同的数据类型成员组成, 但在任何同一时刻, 联合中只存放了一个被选中的成员(所有成员共用一块...
    vbuer阅读 1,573评论 0 0
  • 利润表基本概念 首先,回顾一下三大报表,这个表格贯穿了我们整个课程,大家非常熟悉了吧: 它们的作用是: 今天首先回...
    鱼香肉丝_89阅读 2,999评论 0 0