2017-01-16 8 views
0

Я не ожидал, что new не изменит переменные экземпляра, если переменные экземпляра уже назначены.Локальное использование нового ключевого слова

Правильно ли я понял?

class Foo { 
    String name = "Java"; 
} 
class Main { 
    public static void main(String args[]) { 
     Foo foos[] = { new Foo(), new Foo() }; 
     foos[0].name = "bar"; 
     for (Foo c : foos) c = new Foo(); 
     for (Foo c : foos) System.out.println(c.name); 
     for (Foo c : foos) c.name = "baz"; 
     for (Foo c : foos) System.out.println(c.name); 
    } 
} 

Выход

bar 
Java 
baz 
baz 

В приведенном выше примере, new работает больше как заливкой объекта к тому же классу уже он. Каково практическое применение этого поведения?

+2

Оператор 'new' просто выполняет свою работу, которая заключается в создании новых объектов. Здесь я ничего не вижу, что требует объяснения. –

+1

Это действительно непонятно, что вы имеете в виду здесь ... У вас есть 3 использования «нового» - из чего вы удивлены? И что это связано с локалями? Что вы ожидаете от результата? Вы удивлены тем, что 'c = new Foo();' фактически не изменяет значение в коллекции? Если это так, то это * ничего * связано с 'new'. –

+0

Существует четыре независимые переменные 'c'. Нет переназначения, кроме первого цикла. Но это не влияет на массив. – Albjenow

ответ

3

Это потому, что Java всегда переходящий значение. Переменная c не отражает элемент массива, но его ссылочное значение копируется. Итак, сначала c указывает на значение элемента массива, но когда вы переназначаете c, используя c = new Foo(), переменная c укажет на что-то еще. По этой причине сам элемент массива не подвержен влиянию.

  1. В этом коде

    for (Foo c : foos) 
    

    ссылка на элемент массива (например foos[0]) копируется в c.

  2. Но когда вы назначаете новый Foo экземпляр c, он не отражается на массиве, вы просто присвоили что-то c.

    c = new Foo(); 
    
  3. В следующей итерации цикла, следующий элемент переведен на c, в результате чего объект, созданный c = new Foo() свободно в памяти. Скоро будет собран мусор.

Я заметил, что вы пришли из мира C, что объясняет путаницу. Но в Java аргументы, переданные методу или ссылка на элемент в цикле foreach, всегда копируются. This post объясняет дополнительную информацию об этом поведении.