2015-08-12 5 views
0

Есть ли причина предпочесть использование переменной общего экземпляра в классе по сравнению с локальной переменной и методы возвращают экземпляр? Или это плохая практика?Общая переменная экземпляра и локальная переменная

import package.AClass; 

public class foo { 
    private AClass aVar = new AClass(); 

    // ... Constructor 

    public AClass returnAClassSetted() { 
    doStuff(aVar); 

    return avar; 
    } 

    private void doStuff(AClass a) { 
    aVar = a.setSomething(""); 
    } 
} 

против

import package.AClass; 

public class foo { 

    // ... Constructor 

    public AClass returnAClassSetted() { 
    AClass aVar = new AClass(); 
    aVar = doStuff(); 

    return aVar; 
    } 

    private AClass doStuff() { 
    AClass aVar1 = new AClass(); 
    aVar1.setSomething(""); 

    return aVar1; 
    } 
} 

Первый один имеет больше смысла для меня во многих отношениях, но я часто вижу код, который делает второй. Благодаря!

+0

Это действительно зависит от задачи ... – brso05

+0

Переменные экземпляра должны использоваться для объекта * state *. То есть, информация, которая должна оставаться в объекте между доступом к его методам. Объем информации должен быть как можно меньше. – RealSkeptic

+1

Пожалуйста, исправьте свой код, чтобы сделать его читаемым. В java нет ключевого слова '' Class'', нет переменной '' AVar1''. Java - это случайный случай *. – user996142

ответ

0

Ваше имя класса должно быть Foo.

Две версии, которые у вас есть, не совпадают, и это должно зависеть от вашего варианта использования.

Первая версия возвращает тот же объект AClass, когда разные абоненты звонят returnAClassSetted(), используя тот же объект Foo. Если одно из них изменит состояние возвращаемого объекта AClass, все они увидят это изменение. Ваш класс Foo является фактически Singleton.

Вторая версия возвращает новый объект AClass каждый раз, когда вызывающий абонент вызывает метод returnAClassSetted(), используя один и тот же или другой объект Foo. Ваш класс Foo является фактически Builder.

Кроме того, если вы хотите использовать вторую версию, снимите AClass aVar = new AClass(); и просто используйте AClass aVar = doStuff();. Потому что вы выбрасываете первый объект AClass, созданный new AClass();

2

Переменные экземпляра разделяются всеми методами в классе. Когда один метод изменяет данные, на него может влиять другой метод. Это означает, что вы не можете понять какой-либо один метод самостоятельно, так как он зависит от кода в других методах в классе. Порядок, в котором вызваны методы, может повлиять на результат. Методы не могут быть реентерабельными. Это означает, что если метод вызывается снова, прежде чем он завершит его выполнение (скажем, он вызывает метод, который затем вызывает его, или запускает событие, которое затем вызывает вызов слушателя), он может ошибочно или неправильно вести себя, поскольку данные общий. Если этого не было достаточно потенциальных проблем, когда у вас многопоточность, данные могут быть изменены во время использования, что приводит к непоследовательности и затруднению воспроизведения ошибок (условий гонки).

Использование локальных переменных позволяет минимизировать область с минимальным количеством требуемого кода. Это облегчает понимание и отладки. Это позволяет избежать условий гонки. Легче гарантировать, что метод реентерабелен. Хорошей практикой является минимизация объема данных.

+0

Я вижу, поэтому, если у меня есть метод doStuff для второго варианта public; вызов обоих методов снаружи гарантирует, что они не переписывают один и тот же объект. В то время как первый случай будет использоваться, если я хочу, чтобы один метод перезаписывал один и тот же объект. –

0

Это не вопрос «да/нет». Это в основном зависит от ситуации и ваших потребностей. Наилучшей практикой считается объявление переменной в наименьшей области. Однако могут быть некоторые случаи (например, в этом случае), где, в зависимости от задачи, лучше объявить ее внутри/вне методов. Если вы объявите их снаружи, это будет один случай, и с другой стороны это будет два.

0

Свойства экземпляра представляют состояние конкретного экземпляра этого класса. Может быть, больше смысла думать о конкретном примере. Если класс Engine, одно из свойств, которые могли бы представлять состояние двигателя может быть

private boolean running; 

... так дали экземпляр двигателя, вы могли бы назвать engine.isRunning(), чтобы проверить состояние.

Если данное свойство не является частью состояния (или состава) вашего класса, то оно может быть лучше всего подходит для локальной переменной внутри метода, в качестве детали реализации.

+0

Спасибо, я тоже буду помнить об этом! –

0

В значениях переменных экземпляра значения по умолчанию равны нулю, поэтому, если это ссылка на объект, 0, если это и int.

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

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

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