Всегда ли параметры функции Java передаются по значению?
Просто быстрый вопрос о том, как параметры передаются в 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))? Мое предположение заключается в том, что они будут, поскольку объектные переменные (указатели объектов) всегда передаются по значению?
Ответы
Ответ 1
Вы неверно понимаете, что здесь происходит - ссылки на объекты передаются по значению (копия ссылки сделана), поэтому stdout и stderr не изменяются, когда вы вызываете tidy. Копии, которые сделаны из них, изменяются при выполнении строки 2 из tidy
.
Передача параметров в Java является источником путаницы для многих людей. Здесь хорошее объяснение.
Ответ 2
От Джеймса Гослинга в "Язык программирования Java":
"... В Java существует ровно один режим передачи параметров - передается по значению - и это упрощает задачу..."
Я думаю, что окончательный авторитет в этом.
Ответ 3
Параметры Java всегда имеют значение pass-by-value, period.
Вот милая статья, объясняющая феномен:
http://www.javaranch.com/campfire/StoryPassBy.jsp
В вашем случае не имеет значения, является ли это pbr или pbv, потому что вы повторно назначаете sb новому объекту (вызывая buffer = new StringBuffer(...)
и buffer.subString(...)
не мутирует сам объект).
Ответ 4
Нет, stdout и stderr не будут изменены, и да, параметры передаются по значению.
Переменная "buffer" будет установлена равной stdout, то есть буфер сначала укажет на тот же объект. Когда буфер изменен, чтобы указать на новый объект, старая ссылка stdout будет по-прежнему указывать на старый объект.
Ответ 5
Ваше предположение неверно. Почему?
Поскольку параметры всегда передаются по значению.
Когда вы выполните:
buffer = new StringBuffer(buffer.substring(i));
вы назначаете новый StringBuffer
для локальной ссылки, которая была скопирована из ссылки на параметр. Таким образом, исходный буфер не изменяется.