java 引用 内存_Java内存分配及值、引用的传递

关于堆栈的内容网上已经有很多资料了,这是我找的加上自己理解的一篇说明文:

一、内存区域类型

1.寄存器:最快的存储区, 由编译器根据需求进行分配,我们在程序中无法控制;

2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(对象可能在常量池里)(字符串常量对象存放在常量池中。);

3. 堆:存放所有new出来的对象;

4. 静态域:存放静态成员(static定义的);

5. 常量池:存放字符串常量和基本类型常量(public static final)。有时,在嵌入式系统中,常量本身会和其他部分分割离开(由于版权等其他原因),所以在这种情况下,可以选择将其放在ROM中 ;

6. 非RAM存储:硬盘等永久存储空间 (摘抄地址:http://blog.csdn.net/clam_clam/article/details/6829960)

二、栈中放的东西,图示:

int i =2;//基本类型变量的数据

String s="abc";//s为引用

String s1=new String("a");//s1也是引用

9aeaec81cad13cf44214d6b06501e87d.png

三、堆存放示意图:

b70058e821429011a688eecd856cffbe.png

对于String类的对象特别说明一下:

String a="abc";//代码在执行后在常量池中创建了一个值为abc的String对象;

String b="abc";//执行时,因为常量池中存在abc,所以就不再创建新的String对象了

String c=new String("xyz");

String d=new String("xyz");/***class被加载时,"xyz"被作为常量读入,在常量池中创建了一个共享的值

*为"xyz"的String对象;然后调用到new String("xyz")的时候,会在堆里创建这个String("xyz")对象。*/String s1=new String("xyz");//创建了两个对象(一个在常量池中,一个在堆中),一个引用(栈中)

String s2=new String("xyz");//创建一个对象(堆中),一个引用(栈中)

String s3="xyz";//创建一个对象放在常量池中,一个引用(栈中)

String s4="xyz";//创建一个引用,指向"xyz"

四、按值传入还是引用传入

理解了堆栈数据存储,再来理解一下值传递和引用传递的概念;

1、基本类型:

public classChangeGender{public static voidchange(String gender) {

gender="女";

System.out.println("手术期间: gender= " +gender);

}public static voidmain(String[] args) {

String gender="男";

System.out.println("变性前"+gender);

change(gender);

System.out.println("变性后:"+gender);

}

输出结果:

变性前:男

手术期间:女

变性后:男

经过了痛苦的手术后,发现自己还是个男的,这是为啥?换个写法你就懂了:

public classChangeGender{public static voidchange(String girl) {

girl="女";

System.out.println("手术期间: gender= " +girl);

}public static voidmain(String[] args) {

String boy="男";

System.out.println("变性前"+boy);

change(boy);

System.out.println("变性后:"+boy);

}

输出结果:

变性前:男

手术期间:女

变性后:男

懂了吧,传给change()方法的参数值由boy传递,传完就由girl这个变量来处理了,手术期间的那个值是girl这个变量的值,手术前后的那个值是boy的。这个过程可以用一个故事总结一下:一个男人不想做男人了,准备做手术换个性别,于是打电话给快递小哥(变量boy)把他送到医院手术台上,快递小哥见到医生后,把那个男的交给了会变性的医生(方法change()),快递小哥就走了(快递小哥还是快递小哥),医生开始工作,把他的性别变成女的(girl="女"),那个男的确实手术成功了,只是我们打印的变性后的属性是快递小哥的。故事结束,完美!

2、引用传值

引用要这样来理解:它是一根绳子,它系着一个球(对象),但它不是球(对象),我们想找到球(对象),就得先找对应的绳子。

4fb6437a964f1d3755f172d223c5686f.png

看栗子:

public classUser {privateString age;public voidgetGirlAge(User user) {

user.setAge("18");

}//getter、setter方法

publicString getAge() {returnage;

}public voidsetAge(String age) {this.age =age;

}public static voidmain(String[] args) {

User user= new User();//创建一个新的User对象

user.setAge("20");//设置年龄 ①

user.getGirlAge(user);//调用User的save()方法

System.out.println(user.getAge());//输出年龄 ②

}

}

输出的结果是什么?

18

为啥是这个结果,还是来说个故事,你同学给你介绍对象,说这姑娘白白嫩嫩,漂亮地一塌糊涂,你说好呀好呀,那她多大呀?你同学是马大哈,记不得年龄,就跟你说20岁(user.setAge("20")),然后你说确定吗?我才19岁,年龄大的一概不考虑,于是你同学就去找她的年龄(public void getGirlAge(User user)),得到了年龄并把这个年龄保存在大脑中(user.setAge("18")),然后打电话跟你说的时候,把年龄的信息从大脑里拿出来(user.getAge()),18岁是你可以接受的年龄,于是你们就安排见面了...再一次,完美。

那再加个东西,你们看看:

public classUser {privateString age;public voidgetGirlAge(User user) {

user=new User();//创建新的user对象

user.setAge("18");

}//getter、setter方法

publicString getAge() {returnage;

}public voidsetAge(String age) {this.age =age;

}public static voidmain(String[] args) {

User user= new User();//创建一个新的User对象

user.setAge("20");//设置年龄

user.getGirlAge(user);//调用User的save()方法

System.out.println(user.getAge());//输出年龄

}

}

这里输出的值是20,看来对象是谈不成了,这过程中到底发生了什么呢?原来是你的同学找那个姑娘的年龄的时候,发现那个姑娘把你同学拉黑了,你同学好面子,还是得给你介绍,于是又找了一个新的姑娘(user=new User();),还把年龄设成了18岁,你等啊等,等了半年也没等到,于是你开始着急了,想知道这个姑娘的年龄到底是多少,于是打印输出姑娘年龄,可是这个姑娘还是第一个姑娘(你也根本就不知道还有第二个姑娘),得到的就是20,年龄虽然比你大一点,可是半年时间,你也想清楚了,年龄大一点体贴也挺好。于是。。。好了,依然完美!

就扯这么多,堆栈中放的东西都是固定的,大家记忆一下就好,很简单的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值