博文出处:http://atleeon.com/code/2013/11/28/java-swap-value/
晚上看到一篇非常有意思的文章《Swapping of two numbers》,讲的是如何用Java语言实现swap方法。看到作者的代码,实在逗坏了,而且这篇文章在Google搜索如何实现Java swap中排名非常靠前,如果感兴趣可以看一下文章以及评论。
##Bad Swap 实际上类似作者的交换代码,在Java中是无效的。原因是Java中参数传递是严格的按照value传递的。所以只改变参数本身的数值,并不会影响外面。这一点很好理解。
public void badSwap(int a, int b){
int temp = a;
a = b;
b = temp;
}
What about swap two object?
Java的对象实例是用reference来维护的,那么交换两个对象实例会不会有效呢?比如下面的代码结果会怎么样?
public static void swapObj(Point a, Point b) {
Point temp = a;
a = b;
b = temp;
}
public static void main(String[] args) {
Point px = new Point(0,0);
Point py = new Point(1,1);
swapObj(px,py);
}
答案依旧是否定的。原因是当对象作为参数被传递的时候,传进去的实际上也是值,这个值是reference本身的一个拷贝。下图中,当px和py作为参数,进行方法调用时,实际上会生成px和py的一份”拷贝”,注意拷贝的是px和py的值.然后把这对值传入了方法,交换结束后,argx和argy各自指向了新的对象实例,但是方法之外的px和py并没有变化,这就是对象实例交换失败的原因。
Tricky Code
JavaWorld的一个问题中,Tony Sintes给出了下面一段Tricky代码,这段代码的结果是什么?
public void tricky(Point arg1, Point arg2)
{
arg1.x = 100;
arg1.y = 100;
Point temp = arg1;
arg1 = arg2;
arg2 = temp;
}
public static void main(String [] args)
{
Point pnt1 = new Point(0,0);
Point pnt2 = new Point(0,0);
System.out.println("X: " + pnt1.x + " Y: " +pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
System.out.println(" ");
tricky(pnt1,pnt2);
System.out.println("X: " + pnt1.x + " Y:" + pnt1.y);
System.out.println("X: " + pnt2.x + " Y: " +pnt2.y);
}
结果是 赋值成功,交换失败。
X: 0 Y: 0
X: 0 Y: 0
X: 100 Y: 100
X: 0 Y: 0
在方法的内部,赋值操作影响了外面的对象,而交换操作没有效果。原因在arg1.x是通过引用实际上操作了方法外面的对象。而交换操作仍然只是改改变arg1参数本身的值.不会影响外面。
Summary
解释上面例子的两个基本的Rule是:
Java中参数传递是严格的值传递
Java通过reference来维护对象实例
要在一个方法内部实现外部数据的swap,一个基本的前提是可以操作到外面的对象,否则当方法结束返回,所做的操作都没有作用了。本例中我们没有能够操作px和py本身,所以交换操作没有作用。
在C语言中,可以使用传递指针的方式实现有效的Swap(),原因在于C提供了直接的取地址和引用地址的操作。Java则没有提供直接操作内存地址的操作,因此不容易实现形如swap(Object x,Object y)的方法。
Solution
在Java中实现交换,经常借助于数组,一般形式为
public static void exec(Object[] a, int x, int y);
至于原理,可以按照Rule 2 来理解。
分享到:
相关推荐
Java hotswap示例。参考http://www.ibm.com/developerworks/cn/java/j-lo-hotswapcls/
总结:在实际使用中,值传递一方面会占用内存空间,内置类型还好(int等),如果是类(class)类型,赋值可能会是很大一笔开销;另一方面,值传递由于形参和实参内存地址不一样,有些功能并不能实现(swap()),因此,...
JAVA文件热更 相关的配置在HotSwapConf中,可以根据需要修改 热更的文件为java文件,大致是把java文件动态编译成class 然后用agentmain来进行热更 程序启动后,可以自己手动调用HotSwapManager.startTimerTask...
方法的值传递 目录 课程导入 理解方法调用时参数的顺序匹配 理解方法调用时值传递 方法调用时,需要提供实参,它们必须与方法签名中所对应的形参次序相同,这称作参数顺序匹配。 参数顺序匹配 public static void ...
C/C++中swap功能的本质:通过传递变量地址(指针或引用)来交换变量地址中的值。 Java标榜当中对C/C++一个非常大的改进是:Java对程序猿屏蔽了变量地址的概念,降低指针误用。 在Java世界中函数
能够实现参数的交换,swap函数利用变量的引用实现
matlab开发-SWAP结构值。在字符串中查找结构的字段,并将其替换为相应的字段值。
结果,就像光到底是波还是粒子的问题一样,Java 方法的参数是按什么传递的问题,其答案就只能是:即是按值传递也是按引用传递,只是参照物不同,结果也就不同。 4. 正确看待传值还是传引用的问题 要正确的...
基于LH-OAT方法的SWAP-EPIC模型参数敏感性分析,能锋田,姜瑶,综述文章:以背景、研究现状、研究用途的结构书写,篇幅以150~300字左右为宜,不用第一人称做主语,不与正文语句重复。一般研究性
swap logisim emmm 电路
swap电路:当输入c=0时,输出x等于输入a,输出y等于输入b。当输入c=1时,则交换两输出,即输出y等于输入a
用于查看LINUX下进程占用SWAP大小
那些被释放的空间可能来自一些很长时间没有什么操作的程序,这些被释放的空间被临时保存到Swap空间 中,等到那些程序要运行时,再从Swap中恢复保存的数据到内存中。这样,系统总是在物理内存不够时,才进行Swap交换...
修改java类不需要重启jboss的利器--hotswap安装手册
增大swap分区.txt增大swap分区.txt增大swap分区.txt增大swap分区.txt增大swap分区.txt增大swap分区.txt增大swap分区.txt增大swap分区.txt增大swap分区.txt
修改swap分区大小方法,如果安装完linux后感觉swap分区不够用,可以尝试此方法。
Linux之如何在系统使用过程中配置SWAP分区
如果你的硬盘空间已经全部分配给其他分区,也没有多余的预算新添购硬盘,可以利用swap文件的方式增加虚拟的swap空间,不过执行性能会较实际的swap分区差。
faceswap完整项目!
openwrt swap启用脚本