На Java я должен скопировать изменчивую ссылку локально, прежде чем я ее заберу

Если у меня есть следующий

private volatile Collection<Integer> ints;

private void myMethod()
{
   for ( Integer i : ints )
   {
      ...
   }
}

Коллекция ints никогда не изменяется, но вся коллекция может быть заменена другим потоком (так что это неизменная коллекция).

Должен ли я копировать переменную ints локально, прежде чем перебирать ее? Я не уверен, будет ли он доступен несколько раз. т.е. итерация коллекции, другой поток заменяет коллекцию, код продолжает итерацию, но с новой коллекцией.

EDIT: Этот вопрос имеет отношение к дополнительной информации о том, как foreach работает внутри.

Ответы

Ответ 1

Вам не обязательно. Неявно, код будет делать ints.iterator() в любом случае, и с этой точки только использовать этот итератор в старой коллекции.

Ответ 2

Не обязательно, потому что цикл for получит один итератор один раз и зациклится на нем. Этот Iterator привязан к коллекции, которая ее создала.

Таким образом, он не переключит коллекцию в середине цикла.

Ответ 3

Я не думаю, что ребята правы. Правильно, что вы повторяете использование итератора, полученного один раз. Но если целевая коллекция изменяется во время вашей итерации, вы получаете ConcurrentModificationException. Вы можете легко попробовать. Я считаю, что если вы можете изменить коллекцию, вы должны отслеживать это путем синхронизации.