undefined

Статические переменные и методы

Java Syntax
6 уровень , 6 лекция
Открыта

— Новая интересная тема. Хочу рассказать тебе о статических переменных и методах.

— О, я уже слышал про статические переменные. И про статические методы, кажется. Но хотелось бы больше подробностей.

— Когда мы описываем переменные в классе, мы указываем, будут ли эти переменные созданы всего один раз или же нужно создавать их копии для каждого объекта. По умолчанию создаётся новая копия переменной для каждого объекта. Вот как это выглядит:

Объявление класса
class Cat                        //класс
{
    String name;                 //переменная  

    Cat(String name)             //конструктор 
    {
        this.name = name;        //инициализация переменной 
    }
}
Код в методе main:
Cat cat1 = new Cat("Vaska"); //создали один объект, его name содержит строку «Vaska»
Cat cat2 = new Cat("Murka"); //создали один объект, его name содержит строку «Murka»
System.out.println(cat1.name);
System.out.println(cat2.name);
Вывод на экран будет таким:
Vaska
Murka

— Переменные cat1.name и cat2.name, хоть и описаны в одном классе – Cat, но хранят разные значения, т.к. привязаны к разным объектам.
— Это понятно.
— Статические же переменные – существуют в одном экземпляре, и обращаться к ним нужно по имени класса (внутри класса к статической переменной можно обращаться просто по имени):

Объявление класса
class Cat                   //класс
{
    String name;            //обычная переменная
    static int catCount;    //статическая переменная

    Cat(String name)
    {
        this.name = name;
        Cat.catCount++;   //увеличиваем значение статический переменной на 1
    }
}
Код в методе main:
System.out.println(Cat.catCount);
Cat cat1 = new Cat("Vaska");

System.out.println(Cat.catCount);
Cat cat2 = new Cat("Murka");

System.out.println(cat1.name);
System.out.println(cat2.name);
System.out.println(Cat.catCount);
Вывод на экран будет таким:
0
1
Vaska
Murka
2

— Это тоже понятно.

— Методы класса тоже делятся на две категории. Обычные методы вызываются у объекта и имеют доступ к данным этого объекта. Статические методы не имеют такого доступа – у них просто нет ссылки на объект, они способны обращаться либо к статическим переменным этого класса либо к другим статическим методам.

— Статические методы не могут обращаться к нестатическим методам или нестатическим переменным!

— А почему?

— Каждая обычная переменная класса находится внутри объекта. Обратиться к ней можно только имея ссылку на этот объект. В статический метод такая ссылка не передается.

— А в обычные методы передается?

— Да, в обычные методы передается, неявно. В каждый метод неявно передается ссылка на объект, у которого этот метод вызывают. Переменная, которая хранит эту ссылку, называется this. Таким образом, метод всегда может получить данные из своего объекта или вызвать другой нестатический метод этого же объекта.

— В статический метод вместо ссылки на объект передается null. Поэтому он не может обращаться к нестатическим переменным и методам – у него банально нет ссылки на объект, к которому они привязаны.

— Ясно.

— Так работают обычные нестатические методы:

Как выглядит код
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, поэтому статический метод не имеет доступа к нестатическим переменным и методам (ему нечего неявно передать в обычные методы).

— Переменная или метод являются статическими, если перед ними стоит ключевое слово static.

— А зачем такие методы нужны, если они так сильно ограничены?

— У такого подхода тоже есть свои преимущества.

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

— Во-вторых, иногда бывает нужно, чтобы переменная была в единственном экземпляре. Как, например, переменная System.out (статическая переменная out класса System).

— И в третьих, иногда нужно вызвать метод, еще до того, как будет возможность создавать какие-то объекты

— Это когда же?

— А почему, по-твоему, метод main объявлен статическим? Чтобы его можно было вызвать сразу после загрузки класса в память. Еще до того, когда можно будет создавать какие-то объекты.

Комментарии (251)
Чтобы просмотреть все комментарии или оставить свой,
перейдите в полную версию
PSArus 8 уровень, Новосибирск
19 февраля 2021
создание ощущения дежавю - фишка секретной лаборатории джавараш
Igor 10 уровень, Минск
7 февраля 2021
Можно ещё прочитать по этой теме эту лекцию , хотя она не совсем однозначная.
Yury 8 уровень, Москва
6 февраля 2021
в целом все ясно, но не понятно.
Roman Matyukov 15 уровень
1 февраля 2021
Ребята, статические методы и переменные это наши политики и чиновники - они общаются только между собой, а связываться с нами обычными людьми не хотят (IDE так и ругается, говорит: контекст не тот) . А обычные методы и переменные это мы с вами...можем обращаться хоть к кому... был бы толк;)
Сергей 22 уровень
30 декабря 2020
Забыли сказать, статический метод использует меньше памяти!
Даниил Александрович 24 уровень, Тамбов
29 декабря 2020
статика на мой взгляд это вариант реализации глобальных переменных и функций/методов как в других языках.
Andrii 20 уровень
10 декабря 2020
Очень хорошее и понятное обьяснение! https://www.youtube.com/watch?v=GZzVfeY7yEM&list=PLAma_mKffTOSUkXp26rgdnC0PicnmnDak&index=21
Orion 19 уровень, Санкт-Петербург
6 декабря 2020
Ребят, статические методы нужны для того, что бы работать с ними без необходимости создания объекта этого класса. Банальный пример, но класс Math, например, работает по такому принципу. Вот нужно нам число в степень возвести- просто берётся Math.pow(5, 7); и всё. Math-класс, pow-метод, 5 и 7 -само число и в какую степень его возводим. 7 букв, пара цифр и вот у нас есть необходимая нам степень. А представляете сколько мороки было бы если бы в таких простых вычислениях нам бы каждый раз приходилось создавать объект и вызывать его метод?
Александра Зенькович 16 уровень, Минск
4 ноября 2020
первый раз читаю предложение, вижу лишнюю запятую там, где её не должно быть. 0_о перечитываю сначала и вникаю в смысл... читаю далее.... не хватает запятой 0_о перечитываю заново, чтобы понять смысл... не думаю, что у авторов проекта недостаточно финансовых возможностей, чтобы нанять человека, который не позволит таким как я содрогать при виде грамматических и синтаксических ошибок
Бабочка Алушка 17 уровень, Новокузнецк
4 ноября 2020
Статическая переменная класса - это как переменная именно для самого класса, а не для объектов. Если у нас 2 объекта то у обоих одинаковые переменные. Со статической же переменной по другому, независимо сколько объектов создано в классе и с какими параметрами, статическая переменная существует только в одном экземпляре (переменная которая создана только для класса. Н-р можно считать сколько создано объектов по данному классу, как в примере выше static count. Независимо сколько объектов и как они меняются, статическая переменная будет увеличиваться при создании объекта и уменьшаться при удалении объекта)