Ключевое слово static
Давайте рассмотрим схему.
Допустим у нас есть класс. В нашем случае класс Computer. Класс является как бы шаблоном для создания конкретного экземпляра класса. Класс Computer имеет методы on(); off(); load();, которые делают какие-то манипуляции с объектом. И переменные ram; и hdd;, которые будут характеризовать созданный объект. Методы и переменные не статичные. Во время выполнения программы создаются объекты на основе этого класса и тут важно помнить, что для каждого объекта Computer создаются отдельные методы on(); off(); и load(); и эти методы привязаны к конкретному экземпляру класса.
ТО ЕСТЬ БЕЗ ОБРАЩЕНИЯ К ОБЪЕКТУ МЫ НЕ СМОЖЕМ ВЫЗВАТЬ МЕТОД. Также и переменные класса. Для каждого объекта создаются свои переменные класса, которые привязаны к объекту и которые характеризуют состояние данного объекта. В нашем случае для первого, второго и третьего объекта методы on(); off(); load(); будут индивидуальны для каждого объекта, а также переменные ram; hdd; будут индивидуальны. В наших примера в Netbeans мы «через точку» вызывали методы, используя переменную со ссылкой на объект.
Когда мы нажимали точку, компилятор проверял все доступные методы объекта и показывал их. Теперь рассмотрим ситуацию, когда у нас есть статичные элементы.
В классе Computer наиболее подходящий претендент на статичный метод является метод print. Он не работает с переменными объекта, а просто выводит на экран строку и он может быть не привязан к объекту. Следовательно желательно сделать его статичным. Итак на схеме появился новый статичный метод print. При создании статичного элемента выделяет область памяти, которая помечена как область, связанная с классом Computer и в нём как раз находится метод print. Но эта область памяти, помеченная как Computer — это не экземпляр класса, а просто специальная область. Она не создана ключевым словом new, как мы это делали раньше, она создана загрузчиком классов виртуальной машины Java и там находятся все статичные элементы и мы МОЖЕМ ОБРАЩАТЬСЯ К МЕТОДУ БЕЗ СОЗДАНИЯ ОБЪЕКТА! Просто указав название класса и через точку метод print.
То есть как мы видим данный метод не привязан к конкретному экземпляру класса. Почему у объектов также отображается метод print? В объекте 1, в объекте 2, в объекте 3, если этот метод к ним не привязан? Потому что через ссылку на объект мы тоже можем обратиться к статичному методу, но по факту для любого объекта мы будем обращаться к одному и тому же методу, который находится в специальной области памяти.
Отсюда и название static — то есть статичный, не изменяемый, одинаковый для всех объектов. Кроме методов и переменных, статичными могут быть определённые блоки кода, внутренние классы.
Статичные переменные часто являются константами — то есть неизменяемыми значениями в программе. А также статичные переменные могут использоваться как некий аналог глобальных переменных, которые будут видны из любого места программы. То есть все объекты могут изменять какое-то одно значение, которое будет доступно для всех. Например какой-нибудь глобальный счетчик для всей программы.
Также статичные переменные применяются тогда, когда для класса нужно сделать какое-либо поле, которое будет постоянное на протяжении всей программы и которое будет привязано к этому классу.
Статичный метод не имеет права изменять свойство объекта, так как этот метод не привязан к конкретному объекту. Если мы попытаемся обратиться из статичного метода к переменной класса, которая не является статичной, то компилятор нам укажет на ошибку. Потому что не статичные элементы НЕЛЬЗЯ использовать в статичном методе.
Статичные элементы не манипулируют свойствами объекта и не привязаны к конкретному объекту.
Статичные методы и свойства можно вызывать:
1. Через имя класса. Если статичный элемент находится том же классе, откуда мы его вызываем — то название класса можно не писать — можно сразу указывать название статичного элемента. Именно это мы использовали, когда делали простейшую программку для подсчета госпошлины. Также это использовалось с вызовом метода doSmth — мы не писали название класса, а просто сразу начали вызывать этот метод.
2. Через ссылку на экземпляр класса.
Чаще используется первый вариант:
НазваниеКласса.статичный_элемент
Статичный элемент связан не с объектом, а с классом.
Посмотрим как это выглядит в программном коде.
Откроем Netbeans и перейдём в класс Computer. В классе Computer нас интересует метод print();
protected void print (String str){
System.out.println(str);
}
Для того, чтобы сделать print статичным методом, нам необходимо прописать ключевое слово static. К примеру сделаем так:
public static void print (String str){
System.out.println(str);
}
Заметьте, что после того, как мы прописали ключевое слово static — название метода Netbeans отобразил курсивом. Это сделано для визуального отличия статичного метода от не статичного. Также в навигаторе Netbeans метод отображается особым образом — кружочек и по середине палочка.
Это сделано для того, чтобы мы в навигаторе сразу видели какие методы являются статичными, а какие статичными не являются. Теперь давайте попробуем вызвать этот метод. Переходим в MyFirstProgram.
Будем вызывать двумя способами:
1) Через ссылку на класс.
2) Через ссылку на экземпляр класса.
Закомментируем всё, что есть внутри класса main. Для начала вызовем метод при помощи ссылки на класс. Можно просто написать Computer. (вот так с точкой) и Netbeans нам покажет, что метод print нам уже доступен.
public static void main(String[] args) {
Computer.print("Test String");
}
Запустим программу и увидим, что программа выполнилась.
run:
Test String
СБОРКА УСПЕШНО ЗАВЕРШЕНА (общее время: 0 секунд)
Теперь давайте создадим экземпляр класса. Удалим строку Computer.print(«Test String»); и напишем:
Computer comp = new Computer();
При создании будем использовать конструктор без параметров. Возможно, компилятор Netbeans посоветует создать такой конструктор в классе Computer (поскольку у нас там уже были конструкторы с параметрами), сделаем это.
public Computer() {
}
Напишем в классе MyFirstProgram в методе main, comp. поставим точку — Netbeans отобразит доступный метод print. То есть метод print также доступен через ссылку на экземпляр класса. Вызывается один и тот же метод, который находится в определённой области памяти.
Computer comp = new Computer();
comp.print("Test String");
Данный метод также выполнится, однако Netbeans «делает» замечание, что мы делаем доступ к статичному методу print. То есть он «говорит,» что мы бессмысленно создавали объект для того, чтобы сделать доступ к методу print, потому что к методу print мы можем обратиться и без создания объекта. Netbeans «подсказывает,» что мы делаем лишние действия, создаём лишний объект.
Важный момент. Мы можем не создавать объект, а написать вот так:
Computer comp = null;
comp.print("Test String");
то есть у нас нет ссылки на объект какой-либо, у нас есть просто переменная comp типа Computer. И в этом случае статичный метод тоже выполнится, поскольку статичный метод не привязан к экземпляру класса и может вызываться даже без ссылки на экземпляр класса. Достаточно иметь переменную просто нужного типа.
Также следует знать, что в отличие от методов объекта, от обычных методов, которые «живут» вместе с объектом, статичные элементы доступны на протяжении всей программы. То есть уборщик мусора даже если очистит память от каких-либо объектов, статичные элементы останутся.
Статичный метод выполняет какой-либо функционал без привязки к классу, то есть он не манипулирует свойствами объекта и никак не задействован в самом объекте. Просто это как бы вспомогательный метод. Поскольку для каждого объекта Computer не будет создаваться метод print, используя статический метод print мы немного сохраним память.