2012-04-20 3 views
1

При перезаписи существующей переменной someThing типа Thing ниже в методе, что является правильным способом для этого?Каков правильный способ записи этой переменной?

doSomething(someThing); 

void doSomething(Thing thing){ 
    //... 
    thing = new Thing(...); // receives warning in Eclipse 
} 

или

someThing = doSomething(someThing); 

Thing doSomething(Thing thing){ 
    //... 
    return new Thing(...); 
} 

ответ

2

Ваш первый образец не изменяет переменную someThing в вызывающей программе. Назначение отображается только в методе doSomething.

Второй образец изменяет someThing в вызывающем.

Так что, если вы хотите изменить someThing в вызывающем абоненте, вариант 2 является жизнеспособным, а вариант 1 - нет.

См. Is Java "pass-by-reference" or "pass-by-value"?, почему это работает именно так.

Предполагая следующий код и Thing, который имеет метод печати и элемент String.

void foo() { 
    Thing one = new Thing("hello"); // 1 
    bar(one); 
    one.print();     // 5 
} 

void bar(Thing two) {   // 2 
    two = new Thing("bye");  // 3 
}        // 4 

Отнесение в точке 1 первый создает новый объект Thing:

     Thing{data="hello"} 

Затем хранит ссылку на что в one:

one *----- refs --------v 
         Thing{data="hello"} 

При входе bar в точке 2, создается новая ссылка на тот же объект:

one *----- refs --------v 
         Thing{data="hello"} 
two *----- refs --------^ 

Далее строка 3 делает то же самое, как линии 1, то есть создать новый Thing объект:

one *----- refs --------v 
         Thing{data="hello"} 
two *----- refs --------^ 

         Thing{data="bye"} 

затем сохраняет ссылку на этот новый объект в two:

one *----- refs --------v 
         Thing{data="hello"} 

two *----- refs --------v 
         Thing{data="bye"} 

Обратите внимание, что только two модифицировано. Назначение изменяет то, что означает two. не

После возвращения из bar, в строке 4, two выходит из области видимости, то «прощайте» Вещь не имеет ничего ссылающегося его (и в конечном счете мусора).

one *----- refs --------v 
         Thing{data="hello"} 

         Thing{data="bye"} // dead, will be collected 

Таким образом, в точке 5, как вы можете видеть, hello будет печататься - никогда ничего не изменил объект, который one относится.

+0

Ооооооооооооооооооооооооооооооооооооооооооооооолно здесь – Theodor

+0

_why_ это? Это потому, что я переписываю также ссылку на 'someThing' в первом случае? – Theodor

Смежные вопросы