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也是引用
三、堆存放示意图:
对于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、引用传值
引用要这样来理解:它是一根绳子,它系着一个球(对象),但它不是球(对象),我们想找到球(对象),就得先找对应的绳子。
看栗子:
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,年龄虽然比你大一点,可是半年时间,你也想清楚了,年龄大一点体贴也挺好。于是。。。好了,依然完美!
就扯这么多,堆栈中放的东西都是固定的,大家记忆一下就好,很简单的。
java 引用 内存_Java内存分配及值、引用的传递相关推荐
- java 句柄 内存_Java内存区域学习
运行时区域 Java虚拟机在执行Java程序过程中把其所管理的内存划分成若干个不同的数据区域. 程序计数器 当前线程所执行的字节码的指示器.通过改变这个计数器的值来选取下一个需要执行的字节码指令,分支 ...
- java gc内存_Java内存模型和GC机制
最近学习Python的GC机制时,想到了java的GC,忘得差不多了,(⊙﹏⊙)b!!这里便做一下回顾总结.推荐周志明译本的<深入理解Java虚拟机>. 1. Java内存模型 1.1 程 ...
- java gc原理_Java内存管理以及GC工作原理
1.内存管理简介 内存管理的职责为分配内存,回收内存. 没有自动内存管理的语言/平台容易发生错误. 典型的问题包括悬挂指针问题,一个指针引用了一个已经被回收的内存地址,导致程序的运行完全不可知. 另一 ...
- java 及时释放内存_Java 内存释放
问题一什么叫垃圾回收机制 垃圾回收是一种动态存储管理技术它自动地释放不再被程序引用的对象按照特定的垃圾收集算法来实现资源自动回收的功能.当一个对象不再被引用的时候内存回收它占领的空间 ...
- java没错泄露_Java内存泄露问题
内存泄露 很多人在谈论内存泄露问题,当然对于c/c++来说,这个应该是老掉牙的问题,但是很多Java人员也越来越多得讨论这个问题,我这里写个小结,希望对大家有一定的参考价值. 必须先要了解的 1.c/ ...
- java model 原则_java内存模型(Java Memeory Model)
1.java内存模型的重要目标是定义程序中各个访问变量的访问规则,即在虚拟机中将变量存储到内存,和从内存中取出变量的低层细节:这里所说的变量主要包括实例字段,静态字段,构成数组对象的元素不包括局部变量 ...
- new arraylist内存_Java内存泄漏分析工具Memory Analyzer Tool
阅读文本大概需要3分钟. 一个大型的Java项目也许从开发到测试结束并可能不能未发现一些重大的问题,但是在生产环境中还是会出现一些非常棘手的问题,如内存泄漏直接导致服务宕机,遇到这样的问题对于一个经验 ...
- java 引用队列_Java中管理资源的引用队列相关原理解析
当对象改变其可达性状态时,对该对象的引用就可能会被置于引用队列(reference queue)中.这些队列被垃圾回收器用来与我们的代码沟通有关对象可达性变化的情况.这些队列是探测可达性变化的最佳方式 ...
- java 反射 静态域_java 内存 堆 栈
本文主要通过分析Java内存分配的栈.堆以以及常量池详细的讲解了其的工作原理. 一.Java虚拟机内存原型 寄存器:我们在程序中无法控制 栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而 ...
最新文章
- 美国两政府网站被挂马 以性丑闻女星为诱饵
- Spring+Shiro+CAS整合配置笔记
- Android魔法(第二弹)——一步步实现淹没、展开效果
- PowerDesigner反向工程 mysql
- android自定义样式大全:shape,selector,layer-list,style,动画全部内容
- Python 机器学习 利用sklearn构建决策树的实现 2
- Java结构型设计模式之装饰者模式
- 用c语言编写的迷宫游戏代码,C语言编写的迷宫小游戏 源代码
- wsdl2java wsdl文件_使用axis2的wsdl2java把wsdl生成java文件
- nmds与mds的区别_MDS与MSDS的区别
- 如何在程序中调用Bartender软件打印文件模板
- 瘦AP如何连接到无线控制器AC
- 阿里DATAV的使用方法(大屏生成工具)
- 知名建筑景观3D可视化渲染软件lumion10.5
- oracle聚合函数count,聚合函数count里面加条件
- uniapp:索引列表
- 原来微信显示“对方正在输入”,还有这样的含义,真的让人很扎心
- 清华计算几何大作业(一):CG2017 PA1-1 Convex Hull (凸包)
- 2022-2028年中国折叠椅行业发展策略分析及投资前景研究报告
- 香港十大外汇交易商排名名单2020最新版
热门文章
- Hybrid APP 混合开发模式的选择之路(六:JSBridge---Native代码与JS代码的通信桥梁)
- Qt - UI数据双向绑定简易实现
- 中国信息通信研究院技术与标准所高级主管:徐贵宝——我国人工智能政策与产业发展
- SDK(3)讯飞语音
- 云计算公司如何打败亚马逊AWS?
- Mobileye、地平线、芯擎、寒武纪、芯驰等汽车SoC芯片背后的IP供应商——Arteris
- 玩趣树莓派4-外设配件清单
- vue项目使用bootstrap模态框叠加滚动条及蒙层解决方案
- 图解:订单系统的设计
- [乐意黎原创]2019年最新WinRAR 5.71 中文64位版去除烦人的广告的解决方法