关于如何在Java中传递参数的快速问题......
... if ((index = stdout.indexOf(pattern)) != -1) { tidy(stdout, index + pattern.length()); return true; } else if ((index = stderr.indexOf(pattern)) != -1) { tidy(stderr, index + pattern.length()); return true; ... private void tidy(StringBuffer buffer, int i) { logger.info("Truncating buffer: " + buffer); buffer = new StringBuffer(buffer.substring(i)); logger.info("Buffer now: " + buffer); }
在这种情况下,stdout和stderr(用作tidy()中的参数)是否将其值更改为新的StringBuffer(buffer.substring(i))?我的假设是它们作为对象变量(对象指针)总是按值传递?
答案 0 :(得分:14)
你错误地说明了这里发生了什么 - 对象引用是按值传递的(引用的副本是),所以stdout和stderr做不在你调用整理时被修改。当您执行tidy
的第2行时,会修改由它们组成的副本。
Java中的参数传递是很多人混淆的根源。这是a good explanation。
答案 1 :(得分:3)
来自James Gosling的“Java编程语言”:
“...... Java中只有一个参数传递模式 - 按值传递 - 这样可以保持简单......”
我认为这是对此的最终权威。
答案 2 :(得分:2)
Java参数总是按值传递,周期。
这是一篇解释这种现象的可爱文章: http://www.javaranch.com/campfire/StoryPassBy.jsp
在你的情况下,无论是pbr还是pbv都没关系,因为你正在将sb重新分配给一个新对象(通过调用buffer = new StringBuffer(...)
而buffer.subString(...)
不会改变对象本身)
答案 3 :(得分:1)
不,stdout和stderr不会被更改,是的,参数是按值传递的。
变量“buffer”将设置为等于stdout,这意味着缓冲区将首先指向同一个对象。当缓冲区更改为指向新对象时,旧的stdout引用仍将指向旧对象。
答案 4 :(得分:0)
您的假设不正确。为什么呢?
因为函数参数总是按值传递。
当你这样做时:
buffer = new StringBuffer(buffer.substring(i));
您正在为从参数引用复制的本地引用分配新的StringBuffer
。因此,原始缓冲区不会更改。