java的参数传递
来源:互联网 发布:视频提取软件 编辑:程序博客网 时间:2024/06/05 02:03
很早就知道java的数据类型分为基本数据类型(int,double,boolen等)和引用数据类型,所有的类对象其实都是一个引用数据类型。如果方法的参数是类对象,那么对其的操作是可以反映到对象本身的;但是如果参数是基础数据类型,在方法中对其的操作没法反映到原数据上。
举一个老掉牙的例子:
常见错误1
public class Main { public static void main(String[] args) { int a = 1; int b = 2; swap(a, b); System.out.printf("a: %d, b: %d\n", a, b); } public static void swap(int num1, int num2) { int tmp = num1; num1 = num2; num2 = tmp; }}
a: 1, b: 2
由于是值传递,所以swap改变其实是a 和 b 克隆后的两个变量,而对这两个变量的操作不会对a 和 b产生任何影响。但是如果参数是一个类对象,我们对其的改变是可以反映到原对象实例的:
正确代码
public class Main { public static void main(String[] args) { AuxClass a = new AuxClass(1); System.out.println("hashcode a: "+a.hashCode()); AuxClass b = new AuxClass(2); System.out.println("hashcode b: "+b.hashCode()); swap(a, b); System.out.println("hashcode a: "+a.hashCode()); System.out.println("hashcode b: "+b.hashCode()); System.out.printf("a: %d, b: %d\n", a.num, b.num); } public static void swap(AuxClass a, AuxClass b) { int tmp = a.num; a.num = b.num; b.num = tmp; } static class AuxClass { int num; public AuxClass(int n) { num = n; } }}
hashcode a: 589586037hashcode b: 682976601hashcode a: 589586037hashcode b: 682976601a: 2, b: 1
可以看到,a 和 b 对象的num的值改变了。上面是正确的写法,但是,很多人,包括我自己也犯过一个错误,那就是直接修改参数本身!怎么说呢,我们直接来看代码:
常见错误2
public static void swap(AuxClass a, AuxClass b) {// int tmp = a.num;// a.num = b.num;// b.num = tmp; AuxClass tmp; tmp = a; a = b; b = a; }
输出则变为:
hashcode a: 589586037hashcode b: 682976601hashcode a: 589586037hashcode b: 682976601a: 1, b: 2
遇到这个错误的时候我才发现自己以前的一个理解错误:
java中不存在C中的“传引用”,只有值传递!!!!!
熟悉C的程序员都用过指针,对指针可谓爱之深恨之切。指针是指向一块内存地址的内存数据,也就是说指针本身是一个占用4字节内存的int(32 位系统内),而这个int值恰恰又是另一块内存的地址。比如”hello”这个字串,存放在@0x0000F000这个地址到@0x0000F005这段内存区域内(包括0x00的结束字节)。而在@0x0000FFF0到@0x0000FFF03这四个字节内存放着一个int,这个int的值是 @0x0000F000。这样就形成了一个指向”hello”字串的指针。
所以上面【常见错误2】中的swap方法,是将对象实例 a 和 b 的地址(指针)克隆过来,注意,这里我说的是“克隆”;我们姑且用aPointor 和 bPointer称呼它们,它们是新建的两个零时变量,在内存中是占用内存空间的。如果我们通过aPointor 和 bPointer去调用类的成员变量,是可以的,因为它们就是 a和b 实例的地址;但是,然后我们改变 aPointor 和 bPointer的值,那么也就仅仅是改变了两个零时变量,对于实例 a 和 b是没有任何影响的。这也是为什么我在【正确代码】和【常见错误2】中都输出了两个实例的hashCode,从它们的hashCode可以看出,它们的地址从未改变过。
所以,如果是从C/C++转到Java的程序员往往会不习惯这一点,因为在C中,可以传引用,而且【使用参数保存返回值】 或者 【一个方法返回多个值】 在C中是常用技巧,但是在Java中就没有那么方便,不过也并不困难,那就是用一个容器或者自己写一个新的类,把这些参数保证一下。就像前面分析的,通过引用变量操作其对应的实例的成员变量是可以的,但是直接操作引用变量本身是错误的。
- java的参数传递
- JAVA的参数传递
- Java-参数的传递
- Java的参数传递
- java 的参数传递
- Java参数的传递
- Java的参数传递
- java的参数传递
- java的参数传递
- Java的参数传递
- Java的参数传递
- Java参数传递是按值传递的
- JAVA的值传递与参数传递
- java参数的值传递
- java的参数传递问题。
- Java参数传递的讨论
- java 方法的参数传递
- Java参数传递的方式
- 解决数组/字典中的中文出现编码的问题
- [LeetCode] House Robber III
- pear库的安装及使用
- Python 安装MySQL模块出错
- Http协议详解
- java的参数传递
- Linux system monitor
- 1013 of greedy strategy
- 垃圾回收概念与算法
- 分析system_call中断处理过程
- 课程练习一 Problem I id: 1008
- 链式队列的类模板与泛型编程
- Java substring的使用
- 剑指offer面试题10—二进制中1的个数