Java android static class

Ключевое слово static

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

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

У статических методов есть ряд ограничений:

  • они могут вызывать только другие статические методы
  • они могут непосредственно осуществлять доступ только к статическим переменным
  • они не могут ссылаться на члены типа this или super

В большинстве случаев среда разработки или компилятор заметят ошибку программиста и выведут предупреждение о неправильном использовании переменных.

Например, нельзя писать такой код.

В статическом методе main() мы пытаемся задействовать нестатическую переменную number.

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

Инициализирующий блок

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

Любые инициализирующие блоки выполняются до конструкторов.

Создадим класс, который будет содержать статические переменные, статический метод и инициализирующий блок

За пределами класса, в котором они определены, статические методы и переменные могут использоваться независимо от какого-либо объекта. Для этого достаточно указать имя класса, затем точку, а потом имя метода или переменной:

В Android имеются много статических методов и переменных. Например, метод Log.i(). Так как метод является статическим, мы не объявляем Log log = new Log(). Достаточно сразу вызвать метод.

Также часто используется статический метод Toast makeText().

Статическая переменная

Чтобы лучше уяснить механизм работы статической переменной, напишем следующий пример. Создадим класс Cat.

Мы создали две статические переменные. Одну не трогаем, а вторую увеличиваем на единицу в конструкторе.

Переходим в класс активности и проверяем, чему равны эти переменные.

Программа вернёт значения, которые мы сами установили — 0 и 8. Обратите внимание, чтоб мы даже не создавали экземпляры класса, а обращались напрямую к классу.

А теперь создадим двух котов с именами и возрастом. А между котами явно увеличим одну статическую переменную. И снова проверим значения статических переменных.

Первые два значения понятны из предыдущего примера. Затем при создании первого кота, переменная sId автоматически увеличивается на единицу. Вторая переменная остаётся без изменений.

Затем мы явно указываем новое значение для второй переменной, и создаём второго кота, у которого также сработает увеличение на единицу первой переменной. Проверка убедит нас в этом. Было 1 и 8, стало 2 и 15.

Вариант с автоматическим увеличением иногда используют для создания уникального идентификатора объекта, например, товара в магазине. Заводя новый товар, мы автоматически получаем его новый номер, используя статическую переменную.

Источник

Все о ключевых словах static и final

Что такое ключевое слово static?

Чтобы получить доступ к членам класса в Java, нужно сначала создать экземпляр класса, а затем вызвать членов класса с помощью переменной экземпляра. Но иногда нужно получить доступ к членам класса, не создавая никаких переменных.

В таком случае можно воспользоваться ключевым словом static , то есть объявить членов класса статическими. В Java большинство членов служебного класса являются статическими. Вот несколько примеров.

  • java.util.Objects содержит статические служебные операции для метода объекта.
  • java.util.Collections состоит исключительно из статических методов, которые работают с коллекциями или возвращают их.

Где можно употреблять ключевое слово static?

Мы можем использовать это ключевое слово в четырех контекстах:

  • статические методы;
  • статические переменные;
  • статические вложенные классы;
  • статические блоки.
Читайте также:  Android x86 для vmware

Рассмотрим подробнее каждый из перечисленных пунктов.

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

Статические методы также называются методами класса, потому что статический метод принадлежит классу, а не его объекту. Кроме того, статические методы можно вызывать напрямую через имя класса.

В приведенном выше примере метод add — статический, поэтому его можно вызывать напрямую с именем класса. Нет необходимости создавать новый экземпляр класса StaticExample . Но метод multiply не является статическим. Таким образом, для нестатического метода необходимо создать новый экземпляр класса StaticExample .

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

При создании объектов класса в Java каждый из них содержит собственную копию всех переменных класса.

Однако, если мы объявим переменную статической, все объекты класса будут использовать одну и ту же статическую переменную. Это связано с тем, что, как и статические методы, статические переменные также связаны с классом. И объекты класса для доступа к статическим переменным создавать не нужно. Например:

В приведенном выше примере normalVariable — переменная класса, а staticVariable — статическая переменная. Если вы объявите переменную, как показано ниже:

Это похоже на доступ к статической переменной через имя класса:

Здесь статические переменные — переменные уровня класса. Поэтому, если вы обращаетесь к статическим переменным через переменную экземпляра объекта, то это отражается на соответствующей статической переменной уровня класса. Таким образом, статические переменные всегда имеют одно и то же значение. Но переменная экземпляра сохраняет отдельное значение в каждом экземпляре объекта. Таким образом, приведенный выше фрагмент кода выведет:

Статические переменные — редкость в Java. Вместо них применяют статические константы. Они определяются ключевым словом static final и представлены в верхнем регистре. Вот почему некоторые предпочитают использовать верхний регистр и для статических переменных.

Статические блоки

Здесь мы видим статический блок с синтаксисом:

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

Класс может содержать несколько статических блоков, а каждый из них выполняется в той же последовательности, в которой они написаны в коде.

Вывод приведенного выше фрагмента кода выглядит следующим образом, потому что переменная staticVariable обновлена вторым значением статического блока.

Вложенный статический класс

В Java можно объявить класс внутри другого класса. Такие классы называются вложенными классами. Они бывают двух типов: статические и нестатические.

Вложенный класс является членом заключающего его класса. Нестатические вложенные классы (внутренние классы) имеют доступ к другим членам заключающего класса, даже если они объявлены приватными. Статические вложенные классы не имеют доступа к другим членам заключающего класса.

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

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

В приведенном выше примере видно, что внутренний класс MyInnerClass может получить доступ ко всем методам и переменным внешнего, включая приватные переменные. Статическому внутреннему классу, напротив, недоступны какие-либо методы или переменные внешнего класса.

Где в памяти Java хранятся статические классы и переменные?

Вплоть до 8-й версии Java статические методы и переменные хранились в пространстве permgen. Но потом было введено новое пространство памяти, называемое метапространством — в нем хранятся все эти имена и поля класса, методы класса с байт-кодом методов, пул констант, JIT-оптимизации и т. д. Причина удаления permgen в Java 8.0 в том, что очень сложно предсказать необходимый размер permgen.

Зачем нужно ключевое слово final?

В Java при объявлении сущности можно воспользоваться ключевым словом final . Оно предполагает, что значение не может быть изменено в будущем. Ключевое слово final может применяться для переменной, метода и класса.

  • Конечная переменная предназначена для создания постоянных значений.
  • Конечный метод предотвращает переопределение метода.
  • Конечный класс предотвращает наследование.

Что такое конечная переменная и когда ей стоит воспользоваться?

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

Читайте также:  Ассистент настройки ios перенести данные с андроид как включить

Существует три способа инициализации конечной переменной.

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

Когда следует применять конечную переменную

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

Где использовать конечные классы

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

Первое, безусловно, заключается в предотвращении наследования, так как конечные классы не могут быть расширены. Например, все классы-оболочки, такие как Integer , Float и т. д. — конечные классы.

При попытке расширить конечный класс компилятор выдаст следующее исключение:

Другое применение final с классами заключается в создании неизменяемого класса, подобного предопределенному классу String . Нельзя сделать класс неизменяемым, не сделав его конечным.

Когда использовать конечные методы

Когда метод объявляется с ключевым словом final , он называется конечным методом. Такой метод не может быть переопределен. Это присутствует в классе Object — ряд его методов конечные. С ключевым словом final объявляются методы, для которых необходимо следовать одной и той же реализации во всех производных классах. Фрагмент ниже иллюстрирует метод с ключевым словом final :

Здесь происходит попытка переопределить метод final из родительского класса. Java этого не позволяет и выдает следующее исключение:

Надеемся, теперь вы хорошо поняли ключевые слова static и final .

Источник

10 заметок о модификаторе Static в Java

Статические поля

Статический блок

Статический метод

Статический класс в Java

Что должен знать каждый программист о модификаторе Static в Java

Вы НЕ можете получить доступ к НЕ статическим членам класса, внутри статического контекста, как вариант, метода или блока. Результатом компиляции приведенного ниже кода будет ошибка:

Это одна из наиболее распространённых ошибок допускаемых программистами Java, особенно новичками. Так как метод main статичный, а переменная count нет, в этом случае метод println , внутри метода main выбросит “Compile time error”.

В отличие от локальных переменных, статические поля и методы НЕ потокобезопасны (Thread-safe) в Java. На практике это одна из наиболее частых причин возникновения проблем связанных с безопасностью мультипоточного программирования. Учитывая что каждый экземпляр класса имеет одну и ту же копию статической переменной, то такая переменная нуждается в защите — «залочивании» классом. Поэтому при использовании статических переменных, убедитесь, что они должным образом синхронизированы (synchronized), во избежание проблем, например таких как «состояние гонки» (race condition).

Статические методы имеют преимущество в применении, т.к. отсутствует необходимость каждый раз создавать новый объект для доступа к таким методам. Статический метод можно вызвать, используя тип класса, в котором эти методы описаны. Именно поэтому, подобные методы как нельзя лучше подходят в качестве методов-фабрик ( factory ), и методов-утилит ( utility ). Класс java.lang.Math — замечательный пример, в котором почти все методы статичны, по этой же причине классы-утилиты в Java финализированы ( final ).

Другим важным моментом является то, что вы НЕ можете переопределять ( Override ) статические методы. Если вы объявите такой же метод в классе-наследнике ( subclass ), т.е. метод с таким же именем и сигнатурой, вы лишь «спрячете» метод суперкласса ( superclass ) вместо переопределения. Это явление известно как сокрытие методов ( hiding methods ). Это означает, что при обращении к статическому методу, который объявлен как в родительском, так и в дочернем классе, во время компиляции всегда будет вызван метод исходя из типа переменной. В отличие от переопределения, такие методы не будут выполнены во время работы программы. Рассмотрим пример:

Вывод в консоль:

Внутри родительского класса/статического метода

Код наглядно демонстрирует: несмотря на то, что объект имеет тип Car , вызван статический метод из класса Vehicle , т.к. произошло обращение к методу во время компиляции. И заметьте, ошибки во время компиляции не возникло!

Читайте также:  Взлом fifa 14 для андроид

Объявить статическим также можно и класс, за исключением классов верхнего уровня. Такие классы известны как «вложенные статические классы» ( nested static class ). Они бывают полезными для представления улучшенных связей. Яркий пример вложенного статического класса — HashMap.Entry , который предоставляет структуру данных внутри HashMap . Стоит заметить, также как и любой другой внутренний класс, вложенные классы находятся в отдельном файле .class. Таким образом, если вы объявили пять вложенных классов в вашем главном классе, у вас будет 6 файлов с расширением .class. Ещё одним примером использования является объявление собственного компаратора ( Comparator ), например компаратор по возрасту ( AgeComparator ) в классе сотрудники ( Employee ).

Модификатор static также может быть объявлен в статичном блоке, более известным как «Статический блок инициализации» ( Static initializer block ), который будет выполнен во время загрузки класса. Если вы не объявите такой блок, то Java соберёт все статические поля в один список и выполнит его во время загрузки класса. Однако, статичный блок НЕ может пробросить перехваченные исключения, но может выбросить не перехваченные. В таком случае возникнет «Exception Initializer Error». На практике, любое исключение возникшее во время выполнения и инициализации статических полей, будет завёрнуто Java в эту ошибку. Это также самая частая причина ошибки «No Class Def Found Error», т.к. класс не находился в памяти во время обращения к нему.

Полезно знать, что статические методы связываются во время компиляции, в отличие от связывания виртуальных или не статических методов, которые связываются во время исполнения на реальном объекте. Следовательно, статические методы не могут быть переопределены в Java, т.к. полиморфизм во время выполнения не распространяется на них. Это важное ограничение, которое необходимо учитывать, объявляя метод статическим. В этом есть смысл, только тогда, когда нет возможности или необходимости переопределения такого метода классами-наследниками. Методы-фабрики и методы-утилиты хорошие образцы применения модификатора static. Джошуа Блох выделил несколько преимуществ использования статичного метода-фабрики перед конструктором, в книге «Effective Java», которая является обязательной для прочтения каждым программистом данного языка.

Важным свойством статического блока является инициализация. Статические поля или переменные инициализируются после загрузки класса в память. Порядок инициализации сверху вниз, в том же порядке, в каком они описаны в исходном файле Java класса. Поскольку статические поля инициализируются на потокобезопасный манер, это свойство также используется для реализации паттерна Singleton . Если вы не используется список Enum как Singleton , по тем или иным причинам, то для вас есть хорошая альтернатива. Но в таком случае необходимо учесть, что это не «ленивая» инициализация. Это означает, что статическое поле будет проинициализировано ещё ДО того как кто-нибудь об этом «попросит». Если объект ресурсоёмкий или редко используется, то инициализация его в статическом блоке сыграет не в вашу пользу.

Во время сериализации, также как и transient переменные, статические поля не сериализуются. Действительно, если сохранить любые данные в статическом поле, то после десериализации новый объект будет содержать его первичное (по-умолчанию) значение, например, если статическим полем была переменная типа int , то её значение после десериализации будет равно нулю, если типа float – 0.0, если типа Object – null . Честно говоря, это один из наиболее часто задаваемых вопросов касательно сериализации на собеседованиях по Java. Не храните наиболее важные данные об объекте в статическом поле!

И напоследок, поговорим о static import . Данный модификатор имеет много общего со стандартным оператором import , но в отличие от него позволяет импортировать один или все статические члены класса. При импортировании статических методов, к ним можно обращаться как будто они определены в этом же классе, аналогично при импортировании полей, мы можем получить доступ без указания имени класса. Данная возможность появилась в Java версии 1.5, и при должном использовании улучшает читабельность кода. Наиболее часто данная конструкция встречается в тестах JUnit, т.к. почти все разработчики тестов используют static import для assert методов, например assertEquals() и для их перегруженных дубликатов. Если ничего не понятно – добро пожаловать за дополнительной информацией.

На этом всё. Все вышеперечисленные пункты о модификаторе static в Java обязан знать каждый программист. В данной статье была рассмотрена базовая информация о статических переменных, полях, методах, блоках инициализации и импорте. В том числе некоторые важные свойства, знание которых является критичным при написании и понимании программ на Java. Я надеюсь, что каждый разработчик доведёт свои навыки использования статических концептов до совершенства, т.к. это очень важно для серьёзного программирования.»

Источник

Оцените статью