函数传对象调用,为什么值没有发生变化?
2006-11-08 23:14
495 查看
public Test{
public void addThree(Integer srcNum)
{
int num = Integer.parseInteger(srcNum);
num += 3;
srcNum = new Integer(num);
}
public static void main(String[] args)
{
Test test = new Test();
Integer srcNum = new Integer(0);
System.out.println("srcNum1:"+srcNum);//1,打印值为0
test.addThree(srcNum);
System.out.println("srcNum2:"+srcNum);//2,打印值为0
}
}
现象:main函数中,对象srcNum传入到addThree函数后,其值被修改,但是2处打印的值依然为0
分析:
1)按照Java的知识,函数传对象调用,对象被改变了以后,其值也会改变,也就是说2处打印的值应为3;
2)按老的传对象调用的理论似乎无法解释,这里存在一个栈调用问题。
main函数分配的栈我们称为栈A,addThree函数分配的栈我们称为栈B,进入addThree函数以后,所有main函数的变量被压入栈A中,同时在栈B中展开addThree函数中的变量。
一旦完成调用addThree函数以后,所有main函数的变量将出栈A,srcNum的值恢复为调用addThree函数之前的值。
3)实际上,对象是在堆中分配的,栈A中存入的只是指向堆中的一个地址。所谓函数传对象调用,只是说堆中的对象值会改变,而指向该对象的地址则不会改变,所以说这里的srcNum在调用前后都是指向了同一个堆中对象的地址。
结论:
上述现象跟传对象调用的理论并不本质矛盾,只是需要你对函数的栈调用、和对象的堆生成有所了解!
public void addThree(Integer srcNum)
{
int num = Integer.parseInteger(srcNum);
num += 3;
srcNum = new Integer(num);
}
public static void main(String[] args)
{
Test test = new Test();
Integer srcNum = new Integer(0);
System.out.println("srcNum1:"+srcNum);//1,打印值为0
test.addThree(srcNum);
System.out.println("srcNum2:"+srcNum);//2,打印值为0
}
}
现象:main函数中,对象srcNum传入到addThree函数后,其值被修改,但是2处打印的值依然为0
分析:
1)按照Java的知识,函数传对象调用,对象被改变了以后,其值也会改变,也就是说2处打印的值应为3;
2)按老的传对象调用的理论似乎无法解释,这里存在一个栈调用问题。
main函数分配的栈我们称为栈A,addThree函数分配的栈我们称为栈B,进入addThree函数以后,所有main函数的变量被压入栈A中,同时在栈B中展开addThree函数中的变量。
一旦完成调用addThree函数以后,所有main函数的变量将出栈A,srcNum的值恢复为调用addThree函数之前的值。
3)实际上,对象是在堆中分配的,栈A中存入的只是指向堆中的一个地址。所谓函数传对象调用,只是说堆中的对象值会改变,而指向该对象的地址则不会改变,所以说这里的srcNum在调用前后都是指向了同一个堆中对象的地址。
结论:
上述现象跟传对象调用的理论并不本质矛盾,只是需要你对函数的栈调用、和对象的堆生成有所了解!
相关文章推荐
- 面试题:为什么其他语言里叫函数调用,objective-c里则是给对象发消息(或者谈下对runtime的理解)
- python同一对象的方法(或函数)没有权利调用该对象的其他方法(或函数)
- 【浅析】把实现放在头文件中的函数模板,为什么没有发生重定义错误
- js text里发生变化调用函数
- Release程序发生奇怪事件,函数调用后,参数发生了异常变化
- 没有被调用的函数其代码为什么会被执行?
- 对象指针为NULL,为什么还是可以调用成员函数
- 虚函数,有的语言里也叫动态函数(DYNAMIC,相对于VIRTUAL),这里的虚,不是没有,而是说,调用对象的类型决定具体的函数。
- 函数调用时栈发生的变化
- 为什么全局变量没有发生变化?
- 存在依赖关系的存储过程与函数,其中的个别对象发生变化后,整个依赖关系是否自动保持?
- linux accept函数与三次握手没有半毛钱的关系------三次握手可能发生在调用accept函数之前
- 为什么可以不创建对象就调用类的成员函数?
- C++对象模型的那些事儿之六:成员函数调用方式
- recorderChild()函数在什么时候调用,为什么不用SetZorder()
- void prinT(Test *pT)//这个函数 这里为什么要用 我完全可以用t3.print()这样来调用类里面函数方法就可以,为何多此一举来这样一步???
- 类的静态方法(函数)中为什么不能调用非静态成员(属性)?
- ora 04091:表XX发生了变化,触发器/函数不能读它(lin49940)
- 为什么不要在构造函数中调用虚函数
- 献给汇编初学者-函数调用堆栈变化分析