Область видимости и доступность
Введено| English | Значение |
|---|---|
| local variable/ˈləʊkl ˈveərɪəbl/ | Локальная переменная |
| scope/skəʊp/ | Область видимости |
| shadows/ˈʃædəʊz/ | Затенение |
Локальная переменная сбрасывается; поле запоминает
- Метод создает
int count = 0;, увеличивает его и возвращает 1. Вызов этого метода дважды возвращает 1 оба раза, поскольку каждый вызов имеет свежую локальную переменную. - Метод, который увеличивает поле объекта, вместо этого возвращает 1, а затем 2 для того же изначально нулевого объекта. Различайте область видимости имени и срок сохранения сохраненного состояния.
Область видимости касается имени в исходном коде
- Область видимости объявления — это часть программы, где его имя может быть использовано. Блоковая локальная переменная находится в области видимости от момента объявления до конца блока; переменная цикла for недоступна после завершения этого цикла.
- Область видимости, права доступа и время жизни отвечают на разные вопросы. Имя может выйти из области видимости, хотя объект, на который оно ранее указывало, по-прежнему доступен через другую ссылку; поля не управляются тем же правилом объявления, что и локальные переменные блоков.
Инициализируйте локальные переменные перед их чтением
- Локальная переменная объявляется внутри метода или блока. Java требует, чтобы она была определенно присвоена до того, как будет прочитано её значение;
int x; return x;является ошибкой компиляции, а не автоматическим возвратом нуля. - Поля экземпляра получают значения по умолчанию во время создания объекта до выполнения инициализаторов и кода конструктора. В примере count начинается с 0; это поле принадлежит каждому объекту и сохраняется между его вызовами методов.
public class ScopeCounter {
private int count;
public int localCount() {
int count = 0;
count++;
return count;
}
public int rememberedCount() {
count++;
return count;
}
public void setCount(int count) {
this.count = count;
}
public static int readCount(ScopeCounter other) {
return other.count;
}
}
Локальное объявление int x; автоматически присваивает x значение нуля, поэтому return x; может скомпилироваться.
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Локальные переменные должны быть определенно присвоены перед использованием; значения по умолчанию для полей к локальным переменным не применяются.
Параметр может скрывать имя поля
- Параметр
countвsetCount(int count)затеняет поле при некачифицированных использованиях этого имени.count = count;присвоил бы параметру самому себе;this.count = count;обновляет поле получателя. - Местная переменная также может затенять поле, как показывает метод localCount. Не делайте вывод о том, что каждое повторное объявление местной переменной допустимо: повторное объявление уже находящейся в области видимости местной переменной во вложенном блоке того же метода является ошибкой компиляции.
Область видимости переменной — это...
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Область видимости — это место, где имя допустимо.
После завершения вызова обычного метода может ли вызывающий код использовать локальную переменную, объявленную только внутри этого метода, по ее локальному имени?
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Локальное имя не находится в области видимости вызывающего кода. Объект, на который указывает эта локальная переменная, тем не менее может быть возвращен и остаться доступным для использования.
Какой вид переменной должен хранить состояние, которое объект должен помнить между вызовами методов?
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Инстансные переменные сохраняются в течение жизни объекта.
Параметр с тем же именем, что и инстансная переменная, перекрывает (скрывает) эту инстансную переменную внутри метода.
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Внутри метода имя означает параметр; используйте this для доступа к полю.
Когда параметр скрывает инстансную переменную того же имени, говорят, что он ___ ее (одно слово).
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Перекрывание скрывает поле за локальным именем.
Доступ зависит от класса-объявителя
- Код внутри ScopeCounter может прочитать приватное поле count другого объекта ScopeCounter через явную ссылку. Показанный статический метод readCount не имеет
this, ноother.countдопустим для ненулевого параметра. - Сторонний класс не может напрямую прочитать это приватное поле. Приватный доступ не ограничен «только моим собственным объектом»; экземплярный метод имеет неявного получателя, тогда как статическому методу требуется явная ссылка для доступа к состоянию экземпляра.
Не объединяйте область видимости имени, инициализацию по умолчанию и приватный доступ в одно правило. Локальная переменная не начинает автоматически с нуля, поле экземпляра нельзя прочитать без качификации из статического метода, а приватное поле другого экземпляра может быть доступно внутри его класса-объявителя.
Область видимости, состояние поля и права доступа
Различайте объявления и контекст доступа; другой экземпляр не становится автоматически недоступным.
Показанный статический метод readCount может прочитать значение other.count, когда other не равен null.
Сложность 1/5 · 100 монет + небольшой бонус за первое выполнение сегодня
Он использует явную ссылку на объект и находится внутри класса, объявляющего приватное поле; неявный this не требуется.
Предскажите нового получателя и возвращаемый объект
- После двух вызовов rememberedCount у объекта a его поле становится равным 2; только что созданный объект b всё ещё имеет count равным 0. Вызов a.localCount() возвращает 1, не изменяя поле a, поскольку локальная переменная count затеняет поле класса.
- Метод может создать объект в локальной переменной и вернуть его ссылку. Имя этой локальной переменной затем становится недоступным для вызывающего кода, но возвращенный объект может оставаться достижимым; конец области видимости имени не уничтожает этот объект.
Область видимости определяет, где имя можно использовать; модификаторы доступа регулируют разрешения; состояние объекта может существовать дольше, чем локальная ссылка. Инициализируйте локальные переменные перед чтением, используйте поля для запоминаемого состояния, специфичного для объекта, и различайте затенение и доступ к приватному полю другого объекта.
Для только что созданного объекта ScopeCounter a вызовите a.rememberedCount() дважды, затем a.localCount(). Что вернет a.localCount()?
Сложность 2/5 · 140 монет + небольшой бонус за первое выполнение сегодня
localCount имеет свежий локальный счетчик, инициализированный нулем; он увеличивает его и возвращает 1, не изменяя поле.