Java всегда передается по значению. К сожалению, они решили назвать местоположение объекта «ссылкой». Когда мы передаем значение объекта, мы передаем ему ссылку . Это запутывает новичков.
Это выглядит следующим образом:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
// we pass the object to foo
foo(aDog);
// aDog variable is still pointing to the "Max" dog when foo(...) returns
aDog.getName().equals("Max"); // true
aDog.getName().equals("Fifi"); // false
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// change d inside of foo() to point to a new Dog instance "Fifi"
d = new Dog("Fifi");
d.getName().equals("Fifi"); // true
}
В приведенном выше примере aDog.getName()
все равно вернет "Max"
. Значение aDog
в main
не изменяется в функции foo
с Dog
"Fifi"
, поскольку ссылка на объект передается по значению. Если он был передан по ссылке, то aDog.getName()
в main
вернет "Fifi"
после вызова foo
.
Аналогично:
public static void main(String[] args) {
Dog aDog = new Dog("Max");
foo(aDog);
// when foo(...) returns, the name of the dog has been changed to "Fifi"
aDog.getName().equals("Fifi"); // true
}
public static void foo(Dog d) {
d.getName().equals("Max"); // true
// this changes the name of d to be "Fifi"
d.setName("Fifi");
}
В выше, Fifi
является именем собаки после вызова foo(aDog)
, потому что имя объекта было установлено внутри foo(...)
. Любые операции, выполняемые foo
на d
, таковы, что для всех практических целей они выполняются на самом aDog
(кроме случаев, когда d
изменен, чтобы указать на другой экземпляр Dog
, например d = new Dog("Boxer")
), .
Это отличный вопрос!
Давайте сосредоточимся на простой команде for
на мгновение. Известная ошибка, связанная с этой командой, когда она используется для переименования файлов . Например:
set i=0
for %%a in (*.txt) do (
set /A i+=1
ren "%%a" !i!.txt
)
В этом случае часто некоторые файлы переименовываются дважды и даже три раза в определенных случаях. Проблема в том, что это поведение зависит от ряда факторов, которые не документированы, например, положение первого переименованного файла внутри списка исходных файлов и нескольких других точек. Аналогично, если файл удаляется до того, как он обработан for
, сообщение «Файл не найден» является обычно выпущено (хотя и не ВСЕ раз). Если новый файл создается в каталоге после , запуск for
начался, то он может или не может быть обработан for
в зависимости (снова) от ряда факторов. Обычный способ избежать проблемы с переименованием - заставить команду for
сначала прочитать весь список файлов, а , затем обработать список:
for /F "delims=" %%a in ('dir /B *.txt') do (
set /A i+=1
ren "%%a" !i!.txt
)
Таким образом, не имеет значения изменения, которые могут быть внесены в файлы на диске: команда for /F
всегда обрабатывает список файлов оригинала .
Аналогичная проблема возникает с for /R
, но в этом случае вероятность проблем больше, потому что есть больше каталогов, в которых могут быть сделаны динамические изменения. Опять же: точное поведение зависит от ряда неизвестных факторов, а способ их избежать - через for /F ... in ('dir /S /B')
. Однако, если вы действительно заинтересованы в этом вопросе, я рекомендую вам провести серию тестов по этому вопросу (и опубликовать результаты). ;)
for /F
. – aschipfl 17 August 2015 в 20:20forfiles
. См. Также мой ответ , включая результаты некоторых тестов. – aschipfl 18 August 2015 в 22:12