重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
我看还是我来回答吧。 注意了!!Java大虾到!!
成都创新互联公司技术团队10余年来致力于为客户提供成都网站设计、网站制作、品牌网站建设、成都营销网站建设、搜索引擎SEO优化等服务。经过多年发展,公司拥有经验丰富的技术团队,先后服务、推广了超过千家网站,包括各类中小企业、企事单位、高校等机构单位。
首先啊,你要知道Java方法调用都是传值的,其次要知道基本类型和对象的区别。
我们来一个个分析你就明白了。
int n=1;
String s="abc";
supper sp=new supper();
这三个量中有一个基本类型,两个对象对吧?那你知到他们有什么区别么?
我来简单的说一下吧。
基本类型很简单,比如整型n就是四字节空间,那这个n存在哪里呢?
存在栈里面(因为他是局部变量)。
由于是传值,那么他就把n的值传过去了,那边的形参也是个局部变量,也存在栈里面(f1调用栈),所以本质上main的n1和f1中的n1是俩n1,所以你改变fi中的n1后mian里面的n1显然不会变。
对象也是传值!!不要说对象是传引用的,如果你老师这样叫你那只能说他不真正理解Java内存结构。
对象是什么?或者说s和sp到底是个什么?
我跟你说,他们首先是个局部变量,存在哪里?和n一样存在main栈里。占多大空间?4个字节!!
撒意思?意思就是所谓对象,实质上就是一指针变量!(Java语法上没指针,但Java实现上有的)
指针的内容或说指针指向哪里?指向堆中的两个对象空间。至于撒是对象空间,我就不细说了,与本问题无关。
所以对象s和sp有两层含义,一是指两个局部变量,而是指这两变量对应的对象空间。
再回到传值的问题上。
调f2、f3同样是传值!!但因为s、sp本身就一指针,所以传的值就是俩对象的内存地址。
好吧,继续分析为什么s不变而sp变。
s不变的原因归结于字符串这个类的特性。不知道你老师告诉过你没有,字符串是不可变的!不知道也没关系,我们看看s的处理过程:
s+="def"; 等价于s = s+"def"
s+"def"怎么处理的你知道么?是把def放入s对象空间中么?不是的。
过程是这样滴:先算出s的长度和def的长度,然后在堆里面开辟一对象空间,之后把s、def都拷进去。而s = s+"def"撒意思呢?那就是考进去之后再把这个新开辟对象的地址放入变量s中去(说过了s是f2的一局部指针类型的变量)。
看看,看看!
main的s把值(对象空间地址)给了f2的s,而你“一不小心”通过s = s+"def"把s中存储的值换成一个新对象的值了。那么f2的s和main的s还指向同一个对象么???不是的。既然不是的,main的s当然不会变?
现在在看看sp
同里,main的sp把自己存的地址拷贝给f3的sp,而你呢?显然没有重新给sp赋值,这也就意味着虽然俩sp是两个局部变量,但这两个变量指向的对象空间是一样滴。
因此,你通过f3的sp操作其成员num,当然会影响main的sp了。
明白了??不明白?我都快累死了你还不明白?去死!
:)
您好,提问者:
java中在内存中划分:栈内存和堆内存。
1、栈内存:栈中是存放一些定义的变量的引用,比如:int a = 1; a那么就存在栈内存中,java中垃圾回收是JVM帮我们完成的,这里比C大大提高了程序员的繁碎。如果想要控制可以使用System.gc();来通知JVM虚拟机执行,但是什么时候执行还是由JVM虚拟机来完成的。
2、堆内存:堆中是存放一些比如数组,map类型等。
你可以先用内存监控工具,进行监控,看看这个功能到底用多少内存。如果不多,其实都不需要实现你说的代码监控的。如果你要使用代码监控,你可是使用Runtime类的几个属性,MaxMemory、FreeMemory、TotalMemory。然后实现个线程,在下载pdf功能前开启线程,然后完毕时关闭线程,如果内存即将溢出(设定个阈值,比如说15%),就报错,跳转到错误页面。
使用java.util包中的Stack类创建一个栈对象
public Object push(Object data);输入数据,实现压栈
public Object pop();输出数据,实现弹栈
public boolean empty()判空
public Object peek();查看栈顶元素
可以去查查API嘛
我也是学java的,大家一起进步。