Вложенный в пакетном исполнении дважды [дубликат]

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")), .

6
задан Community 23 May 2017 в 12:23
поделиться

1 ответ

Это отличный вопрос!

Давайте сосредоточимся на простой команде 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'). Однако, если вы действительно заинтересованы в этом вопросе, я рекомендую вам провести серию тестов по этому вопросу (и опубликовать результаты). ;)

6
ответ дан Aacini 19 August 2018 в 15:49
поделиться
  • 1
    Спасибо за это обширное объяснение! Когда вы говорите об «известной ошибке», не могли бы вы предоставить какие-либо ссылки, если это возможно? Или описываются проблемы вашего собственного опыта? Возможно, я буду проводить интенсивное тестирование по этой теме когда-нибудь, но на данный момент моя квинтэссенция такова: в случае двойников используйте обход for /F. – aschipfl 17 August 2015 в 20:20
  • 2
    Информация была взята из нескольких сообщений на разных сайтах, таких как this : «Операция зависит от того, какой добавочный префикс добавлен. Префикс, начинающий & quot; a & quot; работает по-разному от начала префикса «x». И результат зависит от используемой файловой системы. NTFS представляет имена файлов в алфавитном порядке, но система FAT в RAMDRIVE не сортирует имена & quot ;. Более подробное описание этого пункта здесь – Aacini 17 August 2015 в 21:12
  • 3
    Возможно, вас интересует новый вопрос , который я опубликовал о теме перечисления команды forfiles. См. Также мой ответ , включая результаты некоторых тестов. – aschipfl 18 August 2015 в 22:12
Другие вопросы по тегам:

Похожие вопросы: