undefined

Еще об области действия переменных

Java Syntax
4 уровень , 1 лекция
Доступна

— Профессор всё свою линию гнёт. Все они, старые лекторишки, такие. Всё, что он может рассказать, ты можешь прочесть в книгах. Запомни, ещё ни один человек не научился плавать, прослушав с десяток лекций по этому поводу. Лекции помогают, когда ты 100% в теме и знаешь сам чуть меньше этого профессора.

— Ну, от лекций профессора же есть польза.

— Ага… вернее, мы надеемся, что она есть. Чем больше точек зрения на один и тот же материал ты услышишь, тем больше задумаешься, а как же дела обстоят на самом деле. Услышав только одну точку зрения, ты либо веришь ей, либо нет. Ладно, давай перейдём к делу.

— Давай рассмотрим картинку, которую я уже давал тебе ранее:


public class Variables

{
   private static String TEXT = "The end.";
  ┗━━━━━━━━━━━━━━┛
   public static void main (String[] args)
                          ┗━━━━━━━┛
  {
     System.out.println("Hi");
     String s = "Hi!";
   ┏┗━━━━┛
    System.out.println(s);
    if (args != null)
    {
       String s2 = s;
      ┗━━━━┛
   
      System.out.println(s2);
     
    }
    Variables variables = new Variables();
    System.out.println(variables.classVariables);
    System.out.println(TEXT);
   
  }
 
   public String classVariables;
  ┗━━━━━━━━━━━━━━━┛
   public Variables()
   {
      classVariables = "Class Variables test.";
   }
}

1. Переменная, объявленная в методе, существует/видна с начала объявления до конца метода.

2. Переменная, объявленная в блоке кода, существует до конца этого блока кода.

3. Переменные — аргументы метода — существуют до конца выхода из метода.

4. Переменные класса/объекта существуют все время жизни содержащего их объекта. Их видимость регулируется специальными модификаторами доступа.

5. Статические переменные классов существуют все время работы программы. Их видимость также определяется модификаторами доступа.

— Да, помню эту картинку.

— Вот и отлично. Давай напомню тебе некоторые моменты.

— Все переменные, объявленные внутри методов, существуют/видны с начала их объявления до конца метода (пример: 1).

— Если переменная определена/объявлена в каком-то блоке кода, то она существует до конца этого блока кода (пример: 2).

— Если переменная является аргументом функции, то она существует/видна во всем теле данного метода (пример: 3) .

— Если переменная является переменной класса (пример: 4), то она привязана к конкретному объекту и существует все время, пока существует объект данного класса. Если нет ни одного объекта, то нет и ни одной копии переменной. К переменной можно обращаться (переменная видна) из всех методов класса, независимо от того, объявлены они до неё или после неё. Для каждого объекта создаётся своя, независимая от других объектов, переменная. Доступ к переменной невозможен из статических методов.

— Если переменная объявлена статической – помечена ключевым словом static, то она существует все время, когда существует её класс. Обычно JVM загружает класс в память при первом его использовании, тогда же и инициализируются статические переменные.

Еще об области действия переменных - 1

— В примере выше у нас объявлен класс Cat, у которого есть 4 переменные: a,b,s – обычные, а count – статическая. Если создать несколько объектов такого класса (например, 3 шт.), то каждый из них будет содержать свою собственную копию обычных переменных класса. Статическая же переменная – общая на всех. Формально она даже не находится внутри этих объектов, т.к. существует даже тогда, когда ни одного объекта класса Cat создано не было.

— Вот что произойдет, если мы объявим переменную s статической:

Еще об области действия переменных - 2

— Ага. Вроде понятно.

— А можно объявить одинаковые переменные?

— В методе — нет. Все переменные, объявленные внутри метода, должны иметь уникальные имена. Аргументы метода также считаются его переменными.

— А как насчёт переменных класса?

— Переменные класса тоже должны быть уникальными в рамках каждого конкретного класса.

Но есть исключение – имена переменных метода и переменных класса могут совпадать.

— А если мы в коде изменяем переменную, а таких переменных две, какая будет изменяться?

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

Пример с двумя переменными count
class Main
{
    public int count = 0;     //объявили переменную класса

    public void run()
    {
        count = 15;           //обращение к переменной класса
        int count = 10;       //объявили локальную переменную метода
        count++;             //обращение к переменной метода
    }
}

— В этом коде объявлены две переменных count. В строке 3 объявлена переменная класса, а в строке 8 – переменная метода.

— Когда метод run будет исполняться, то произойдет вот что:

— В строке 7 мы обращаемся к переменной класса и присваиваем ей значение 15

— В строке 8 объявляется (создается) новая переменная методаcount. Она закрывает собой переменную класса. Любой дальнейший код в методе будет видеть (обращаться) именно к переменной метода.

— Понятно.

— Переменная метода закрывает собой переменную класса. Т.е. обращение будет происходить к переменной метода. Но к переменной класса тоже можно обратиться, только более сложным способом.

Статическая переменная класса
ClassName.variableName

Примеры:
Cat.catsCount
Обычная переменная класса
this.variableName

Примеры:
this.catsCount

— А что ещё за статические методы и статические переменные?

— Статические методы и переменные привязаны не к объектам класса, а непосредственно к самому классу. Т.е. если мы создадим 10 объектов класса Variables из примера в самом начале уровня, у нас будет 10 переменных classVariable (по одной на каждый объект) и всего одна общая переменная TEXT.

— У меня тут вопрос.

— А чем отличаются статические и нестатические методы?

— Давай рассмотрим, как работает обычный нестатический метод:

Как выглядит код
Cat cat = new Cat();
String name = cat.getName();
cat.setAge(17);
cat.setChildren(cat1, cat2, cat3);
Что происходит на самом деле
Cat cat = new Cat();
String name = Cat.getName(cat);
Cat.setAge(cat,17);
Cat.setChildren(cat, cat1, cat2, cat3);

— При вызове метода в виде «объект» точка «имя метода», на самом деле вызывается метод класса, в который первым аргументом передаётся тот самый объект. Внутри метода он получает имя this. Именно с ним и его данными происходят все действия.

— Нифига себе. Так вот как, оказывается, оно все работает!

— А вот как работает статический метод:

Как выглядит код
Cat cat1 = new Cat();
Cat cat2 = new Cat();
int catCount = Cat.getAllCatsCount();
Что происходит на самом деле
Cat cat1 = new Cat();
Cat cat2 = new Cat();
int catCount = Cat.getAllCatsCount(null);

— При вызове статического метода, никакого объекта внутрь не передаётся. Т.е. this равен null, поэтому статический метод не имеет доступа к нестатическим переменным и методам (ему нечего передать в такие методы в качестве this).

— Хм. Вроде понятно. Хотя как-то поверхностно.

— А вот и дядя Диего… С его задачками.

undefined
4
Задача
Java Syntax, 4 уровень, 1 лекция
Недоступна
Мне не подходит этот возраст…
Подумайте, что делает программа. Исправьте ошибку в программе чтобы переменная age объекта person изменила свое значение. Подсказка: тщательно просмотрите метод adjustAge
undefined
4
Задача
Java Syntax, 4 уровень, 1 лекция
Недоступна
Цена яблок
На аграрной планете Эплсиид главный заработок подавляющего большинства обитателей — продажа лучших в этом уголке Галактики яблок торговым кораблям Федерации и заезжим туристам. Давайте вступим в товарно-денежные отношения с абстрактным покупателем с учётом, что сейчас конец сезона и надо как-то пережить зиму: напишем метод, повышающий цену на яблоки!
Комментарии (712)
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Виталий Уровень 9 Алматы
31 марта 2021
public static class Apple { public static int applesPrice = 0; public static void addPrice(int newprice) { Apple.applesPrice = newprice + Apple.applesPrice; } } не пойму только зачем тогда не статические методы нужны? они же много памяти поедают , лучше делать статическими переменные и обращаться через точку? а? Що скажите? напишите в личку, или щоб я увидел как то)
Виталий Ващук Уровень 10
25 марта 2021
Простое объяснение задачи: 10.Person person = new Person(); 11. System.out.println("Age is: " + person.age); 12. person.adjustAge(person.age); 13. System.out.println("Adjusted age is: " + person.age); 1.public static class Person { 2. public int age = 20; 3. public void adjustAge(int age) { 4. age(this.age) = age + 20; 5.System.out.println("Age in adjustAge() is: " + age); Вывод (11.)Age is: 20 (5.) Age in adjustAge() is: 20 (13.)Adjusted age is: 40 В строке 2 - есть переменная (age), в строке 4 - есть еще одна переменная age: чтобы вызвать переменную age с строки 2 в строке 5 - мы добавляем в строку 4 перед age - this. т.е this.age. В 12 строке делаем ссылку на метод adjustAge из строки 3 и поэтому в строке 13 person.age это ссылка на this.age(5.) В строке 11 person.age это ссылка на строку 2 - public int age. Создатель задачи намеренно сделал такую путаницу!
Женя Билык Уровень 4 Одесса Одесса
19 марта 2021
"Нифига себе. Так вот как, оказывается, оно все работает!" Вот только я такого пока не скажу(
shu Уровень 8 Москва
13 марта 2021
А почему в первой задаче у переменной int age в adjustAge значение 20?
hidden #2328942 Уровень 4
12 марта 2021
1. Если переменная помечена словом "static", то она общая для всех объектов, что будут созданы.(Что-то вроде общей ячейки в банке, из которой все могут брать что-то, и все могут туда класть что-то). 2. Обращение к переменной метода внутри метода - просто ее имя. 3. Обращение к переменной класса внутри метода может быть двух видов: * Если переменная класса НЕСТАТИЧЕСКАЯ - используем конструкцию this.переменная * Если переменная класса СТАТИЧЕСКАЯ - вызываем через имя класса - ClassName.переменная
HF Уровень 41 Харьков Украина
6 марта 2021
Katya Уровень 10 Минск
20 февраля 2021
Ссылка на отличную статью про this https://javarush.ru/groups/posts/608-kljuchevoe-slovo-this-v-primerakh
Михаил Уровень 13 Краснодар Россия
16 февраля 2021
О статических методах и переменных советую почитать в Шилде. В данной лекции материал подается не в самой понятной, разобраться в теме решительно невозможно.
Paper Plane Уровень 7 Санкт-Петербург Россия
28 января 2021
прочитайте тщательнее про переменные метода и класса, в каком случае к какой из них идет обращение. я сначала вообще ничего понять не мог, потом разобрался