Модификаторы Java
Язык Java предоставляет множество модификаторов, которые в основном делятся на следующие две категории:
- Модификаторы доступа
- Модификаторы, не связанные с доступом
Модификаторы используются для определения классов, методов или переменных и обычно размещаются в самом начале инструкции. Проиллюстрируем это на следующем примере:
Модификаторы управления доступом
В Java модификаторы управления доступом можно использовать для защиты доступа к классам, переменным, методам и конструкторам. Java поддерживает 4 различных уровня доступа.
-
default(то есть default, ничего не написано): виден в пределах того же пакета, без использования какого-либо модификатора. Применяется к: классам, интерфейсам, переменным, методам.
-
private: виден в пределах того же класса. Применяется к: переменным, методам.Примечание: нельзя применять к классам (внешним классам)
-
public: виден всем классам. Применяется к: классам, интерфейсам, переменным, методам
-
protected: виден классам в том же пакете и всем подклассам. Применяется к: переменным, методам.Примечание: нельзя применять к классам (внешним классам)。
Уровни доступа можно проиллюстрировать следующей таблицей:
| Модификатор | Текущий класс | Тот же пакет | Подклассы (тот же пакет) | Подклассы (другой пакет) | Другие пакеты |
|---|---|---|---|---|---|
public |
Y | Y | Y | Y | Y |
protected |
Y | Y | Y | Y/N(Описание) | N |
default |
Y | Y | Y | N | N |
private |
Y | N | N | N | N |
Модификатор доступа по умолчанию — без использования каких-либо ключевых слов
Если в определении класса, переменной, метода или конструктора не указан модификатор доступа, то по умолчанию они будут иметь модификатор доступа по умолчанию.
Уровень доступа модификатора доступа по умолчанию — уровень пакета, то есть к нему могут обращаться только другие классы в том же пакете.
Как показано в примере ниже, переменные и методы можно объявлять без использования какого-либо модификатора.
Пример
В приведённом выше примере класс MyClass, его переменная-член x и метод display() определены с использованием модификатора доступа по умолчанию. Класс MyOtherClass находится в том же пакете, поэтому он может обращаться к классу MyClass и его переменным-членам и методам.
Модификатор доступа private - private
Модификатор доступа private — самый строгий уровень доступа, поэтому методы, переменные и конструкторы, объявленные какprivateметоды, переменные и конструкторы могут быть доступны только классу-владельцу, а классы и интерфейсы не могут быть объявлены какprivate。
Переменные, объявленные с типом доступа private, могут быть доступны внешним классам только через public getter-методы в классе.
Использование модификатора доступа private в основном предназначено для скрытия деталей реализации класса и защиты данных класса.
Следующий класс использует модификатор доступа private:
В примере переменная format в классе Logger является private-переменной, поэтому другие классы не могут напрямую получить или задать значение этой переменной. Чтобы позволить другим классам управлять переменной, определены два public-метода: getFormat() (возвращает значение format) и setFormat(String) (устанавливает значение format)
Модификатор доступа public - public
Классы, методы, конструкторы и интерфейсы, объявленные как public, доступны любому другому классу.
Если несколько public-классов, обращающихся друг к другу, распределены по разным пакетам, необходимо импортировать пакет, содержащий соответствующие public-классы. Благодаря наследованию классов все public-методы и переменные класса могут наследоваться его подклассами.
В следующей функции используется модификатор доступа public:
Метод main() программы на Java должен быть объявлен как public, иначе интерпретатор Java не сможет запустить класс.
Модификатор доступа protected - protected
protected нужно проанализировать и объяснить с двух следующих точек зрения:
Подкласс и базовый класс находятся в одном пакете:: Переменные, методы и конструкторы, объявленные как protected, могут быть доступны любому другому классу в том же пакете;
Подкласс и базовый класс не находятся в одном пакете:: Тогда в подклассе экземпляр подкласса может получать доступ к protected-методам, унаследованным от базового класса, но не может получать доступ к protected-методам экземпляра базового класса.
protected может модифицировать элементы данных, конструкторы и методы.Не может модифицировать классы (кроме внутренних классов)。
Интерфейсы и их переменные-члены и методы не могут быть объявлены как protected. Иллюстрацию можно увидеть ниже:

Подклассы могут получать доступ к методам и переменным, объявленным с модификатором protected, таким образом предотвращая использование этих методов и переменных несвязанными классами.
Следующий родительский класс использует модификатор доступа protected, а подкласс переопределяет метод openSpeaker() родительского класса.
Если метод openSpeaker() объявлен как private, то ни один класс, кроме AudioPlayer, не сможет получить доступ к этому методу.
Если openSpeaker() объявлен как public, то все классы смогут получить доступ к этому методу.
Если мы хотим, чтобы метод был виден только подклассам его класса, объявите метод как protected.
protected — один из наиболее сложных для понимания модификаторов доступа к членам класса Java. Для получения дополнительных сведений см.Подробное объяснение ключевого слова protected в Java。
Контроль доступа и наследование
Обратите внимание на следующие правила наследования методов:
Методы, объявленные как public в родительском классе, также должны быть public в подклассе.
Методы, объявленные как protected в родительском классе, должны быть объявлены как protected или public в подклассе и не могут быть объявлены как private.
-
Методы, объявленные как private в родительском классе, не могут быть унаследованы подклассом.
Модификаторы, не связанные с доступом
Для реализации некоторых других возможностей Java также предоставляет множество модификаторов, не связанных с доступом.
Модификатор static используется для изменения методов класса и переменных класса.
Модификатор final используется для изменения классов, методов и переменных. Классы, изменённые с помощью final, не могут быть унаследованы, методы, изменённые с помощью final, не могут быть переопределены классами-наследниками, а переменные, изменённые с помощью final, являются константами и не могут быть изменены.
Модификатор abstract используется для создания абстрактных классов и абстрактных методов.
Модификаторы synchronized и volatile в основном используются в многопоточном программировании.
Модификатор static
-
Статические переменные:
Ключевое слово static используется для объявления статических переменных, независимых от объектов. Независимо от того, сколько объектов создаёт класс, его статическая переменная имеет только одну копию. Статические переменные также называют переменными класса. Локальные переменные не могут быть объявлены как статические переменные.
-
Статические методы:
Ключевое слово static используется для объявления статических методов, которые не зависят от объектов. Статические методы не могут использовать нестатические переменные класса. Статические методы получают данные из списка параметров, а затем вычисляют данные.
Доступ к переменным и методам класса можно осуществлять с помощьюclassname.variablenameиclassname.methodname— метод доступа.
Как показано в примере ниже, модификатор static используется для создания методов класса и переменных класса.
Вывод при запуске приведённого выше примера выглядит следующим образом:
Starting with 0 instances Created 500 instances
Модификатор final
переменные final:
final означает "последний" или "окончательный". После присваивания переменной значения её нельзя переприсвоить. Переменные экземпляра, изменённые с помощью final, должны явно задавать начальное значение.
Модификатор final обычно используется вместе с модификатором static для создания констант класса.
Пример
final-методы
final-методы в родительском классе могут наследоваться подклассами, но не могут быть переопределены подклассами.
Основная цель объявления final-метода — предотвратить изменение содержимого метода.
Как показано ниже, объявите метод с помощью модификатора final.
final-класс
final-класс не может быть унаследован, и никакой класс не может наследовать какие-либо характеристики final-класса.
Пример
Модификатор abstract
Абстрактный класс:
Абстрактный класс нельзя использовать для создания объектов; единственная цель объявления абстрактного класса — расширить класс в будущем.
Класс не может быть одновременно модифицирован как abstract и final. Если класс содержит абстрактные методы, то класс должен быть объявлен как абстрактный класс, иначе возникнет ошибка компиляции.
Абстрактный класс может содержать как абстрактные, так и неабстрактные методы.
Пример
Абстрактный метод
Абстрактный метод — это метод без какой-либо реализации; конкретная реализация предоставляется подклассами.
Абстрактные методы нельзя объявлять как final или static.
Любой подкласс, который наследует абстрактный класс, должен реализовать все абстрактные методы родительского класса, если только подкласс также не является абстрактным классом.
Если класс содержит несколько абстрактных методов, то класс должен быть объявлен как абстрактный класс. Абстрактный класс не обязан содержать абстрактные методы.
Объявление абстрактного метода заканчивается точкой с запятой, например:public abstract sample();。
Пример
synchronized Модификатор
Метод, объявленный с ключевым словом synchronized, может быть доступен только одному потоку одновременно. Модификатор synchronized можно применять к четырём модификаторам доступа.
Пример
transient Модификатор
Когда сериализованный объект содержит переменные экземпляра, изменённые с помощью transient, виртуальная машина Java (JVM) пропускает эту конкретную переменную.
Этот модификатор включается в инструкцию, определяющую переменную, и используется для предварительной обработки типов данных классов и переменных.
Пример
Модификатор volatile
Переменная-член, модифицированная volatile, заставляет потоки перечитывать значение этой переменной-члена из разделяемой памяти при каждом обращении к ней. Более того, когда переменная-член изменяется, потоки вынуждены записывать изменённое значение обратно в разделяемую память. Таким образом, в любой момент два разных потока всегда видят одно и то же значение для данной переменной-члена.
Ссылка на объект volatile может быть null.
Пример
Обычно в одном потоке вызывается метод run() (в потоке, запущенном Runnable), а в другом потоке вызывается метод stop(). ЕслиПервая строкаиспользуется значение active в буфере, тоВторая строкакогда значение active равно false, цикл не остановится.
Но в приведённом выше коде мы использовали volatile для изменения active, поэтому цикл остановится.
Другие расширения