English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
Язык Java предоставляет множество модификаторов, которые в основном делятся на две категории:
Доступные модификаторы
Неявные модификаторы
Модификаторы используются для определения класса, метода или переменной, обычно они помещаются в начале предложения. Мы используем следующий пример для объяснения:
public class ClassName { // ... } private boolean myFlag; static final double weeks = 9.5; protected static final int BOXWIDTH = 42; public static void main(String[] arguments) { // Тело метода }
В Java можно использовать модификаторы доступа для защиты доступа к классам, переменным, методам и конструкторам. Java поддерживает 4 различных уровня доступа.
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 |
Переменные и методы, объявленные с использованием по умолчанию доступа修饰ителя, видимы для всех классов в том же пакете. Переменные в интерфейсе автоматически объявляются как public static final, а методы в интерфейсе по умолчанию имеют доступ public.
Как показано в следующем примере, переменные и методы могут быть объявлены без использования какого-либо修饰ителя.
package defaultPackage; class Logger { void message() { System.out.println("This is a message"); } }
В данном случае, класс Logger имеет по умолчанию доступ修饰итель. И этот класс видим для всех классов, принадлежащих к пакету defaultPackage. Но если мы пытаемся использовать класс Logger в классе за пределами defaultPackage, мы получим компиляционную ошибку.
Частный доступ修饰итель - это наиболее строгий уровень доступа, поэтому объявленный как private методы, переменные и конструкторы могут быть доступны только принадлежащему классу, и классы и интерфейсы не могут быть объявлены как private.
Переменные, объявленные как частный доступ, могут быть доступны извне только через общие getter методы класса.
Использование частного доступа修饰ителя主要用于 скрытие деталей реализации класса и защиту данных класса.
Ниже перечислены классы, использующие частный доступ:
public class Logger { private String format; public String getFormat() { return this.format; } public void setFormat(String format) { this.format = format; } }
В примере переменная format в классе Logger является частной переменной, поэтому другие классы не могут напрямую получить и установить значение этой переменной. Чтобы другие классы могли работать с этой переменной, были определены два public метода: getFormat() (возвращающий значение format) и setFormat(String) (устанавливающий значение format)
Классы, методы, конструкторы и интерфейсы, объявленные как public, могут быть доступны любому другому классу.
Если несколько взаимосвязанных public классов распределены по разным пакетам,则需要 импортировать соответствующие пакеты, в которых находятся public классы. Из-за наследственности класса все公有 методы и переменные могут быть наследованы подклассом.
Следующие функции используют公有 доступ контроля:
public static void main(String[] arguments) { // ... }
Метод main() программы Java должен быть объявлен как public, в противном случае Java-интерпретатор не сможет запустить этот класс.
protected требует анализа и объяснения с двух точек зрения:
Подкласс и базовый класс находятся в одном пакетеТо переменные, методы и конструкторы, объявленные как protected, могут быть доступны любому другому классу в том же пакете;
Подкласс и базовый класс не находятся в одном пакетеТогда в подклассе, пример подкласса может получить доступ к защищенным методам, наследованным от базового класса, но не может получить доступ к методам protected базового класса.
protected может修饰 данные члена, конструкторы, методы членов,Не может修饰类 (за исключением внутренних классов).
Члены интерфейса и переменные и методы интерфейса не могут быть объявлены как protected.
Подкласс может получить доступ к методам и переменным, объявленным с помощью修饰ителя protected, что позволяет защищать методы и переменные от использования несвязанными классами.
Ниже приведен родительский класс с защищенным доступом修饰ителем, который переопределяет метод openSpeaker() родительского класса.
class AudioPlayer { protected boolean openSpeaker(Speaker sp) { // Детали реализации } } class StreamingAudioPlayer extends AudioPlayer { protected boolean openSpeaker(Speaker sp) { // Детали реализации } }
Если метод openSpeaker() объявлен как private, то классы, кроме AudioPlayer, не смогут получить доступ к этому методу.
Если метод openSpeaker() будет объявлен как public, то все классы смогут получить доступ к этому методу.
Если мы хотим, чтобы метод был видим только для подклассов, в котором он находится, мы объявляем его как protected.
Protected - это最难理解的 из всех Java-модификаторов доступа к членам класса.
Пожалуйста, обратите внимание на следующие правила наследования методов:
Методы, объявленные public в суперклассе, в подклассе также должны быть public.
Методы, объявленные protected в суперклассе, в подклассе должны быть объявлены either protected или public, но не private.
Методы, объявленные private в суперклассе, не могут быть наследованы.
Для реализации других функций Java также предоставляет множество неявных модификаторов.
Статический модификатор, используется для修饰ания методов и переменных класса.
Модификатор final, используется для修饰ания классов, методов и переменных, класс, который модифицируется final, не может быть наследован, метод, который модифицируется final, не может быть переопределен классом, наследующим его, переменная, которая модифицируется final, является константой и не может быть изменена.
Модификатор abstract, используется для создания абстрактных классов и абстрактных методов.
Модификаторы synchronized и volatile,主要用于线程 программирование.
Статические переменные:
Ключевое слово static используется для объявления независимых от объекта статических переменных, и независимо от того, сколько объектов классу будет примерено, его статические переменные имеют только одну копию. Статические переменные также называются переменными класса. Локальные переменные не могут быть объявлены как статические переменные.
Статические методы:
Ключевое слово static используется для объявления независимых от объекта статических методов. Статические методы не могут использовать нестатические переменные класса. Статические методы получают данные из списка параметров, затем обрабатывают эти данные.
Доступ к переменным и методам класса можно получить напрямую classname.variablename и classname.methodname для доступа.
Как показано в следующем примере, статический модификатор используется для создания методов и переменных класса.
public class InstanceCounter { private static int numInstances = 0; protected static int getCount() { return numInstances; } private static void addInstance() { numInstances++; } InstanceCounter() {}} InstanceCounter.addInstance(); } public static void main(String[] arguments) { System.out.println("From " + InstanceCounter.getCount() + " instances from "); for (int i = 0; i < 500; ++i){ new InstanceCounter(); } System.out.println("Created " + InstanceCounter.getCount() + " instances"); } }
Результат выполнения примера приведен выше:
От 0 экземпляров Создание 500 экземпляров
Finalные переменные:
Final означает "последний, окончательный", переменная после назначения значения не может быть перезначена. Примеры переменных, помеченных final, должны явно specify начальное значение.
Декоратор final обычно используется вместе с декоратором static для создания классовых констант.
public class Test{ final int value = 10; // Ниже приведен пример объявления констант public static final int BOXWIDTH = 6; static final String TITLE = "Manager"; public void changeValue(){ value = 12; // выведет ошибку } }
Finalные методы
Finalные методы родительского класса могут наследоваться подклассом, но не могут быть переопределены подклассом.
Основной целью объявления метода final является предотвращение изменения его содержимого.
Как показано ниже, метод помечен как final.
public class Test{ public final void changeName(){ // Тело метода } }
Класс final
Классы final не могут быть наследованы, ни один класс не может наследовать какие-либо характеристики класса final.
public final class Test { // Тело класса }
Абстрактный класс:
Абстрактные классы не могут использоваться для создания объектов, единственной целью объявления абстрактного класса является возможность расширения этого класса в будущем.
Класс не может быть одновременно помечен как abstract и final. Если класс содержит абстрактные методы, то он должен быть объявлен как абстрактный класс, в противном случае会出现 компиляторная ошибка.
Абстрактный класс может содержать как абстрактные, так и неабстрактные методы.
abstract class Caravan { private double price; private String model; private String year; public abstract void goFast(); //абстрактный метод public abstract void changeColor(); }
Абстрактный метод
Абстрактные методы представляют собой методы без реализации, чья конкретная реализация предоставляется подклассом.
Абстрактные методы не могут быть объявлены как final и static.
Любой подкласс, наследующий абстрактный класс, должен реализовать все абстрактные методы родителя, за исключением случая, если сам подкласс является абстрактным.
Если класс содержит несколько абстрактных методов, то он должен быть объявлен как абстрактный класс. Абстрактный класс может не содержать абстрактных методов.
Декларация абстрактного метода заканчивается точкой с запятой, например:public abstract sample();.
public abstract class SuperClass { abstract void m(); //абстрактный метод } class SubClass extends SuperClass { //Реализация абстрактного метода void m() { ...... } }
Методы, помеченные ключевым словом synchronized, могут быть доступными только одним потоком в один момент времени. Декоратор synchronized может применяться к четырем доступным декораторам.
public synchronized void showDetails() { ...... }
При сериализации объекта, содержащего переменные, помеченные transient, виртуальная машина Java (JVM) пропускает этот определенный переменный.
Этот декоратор включается в определение переменной и используется для предварительного обработки данных типа класса и переменных.
public transient int limit = 55; //не будет сохранено public int b; //持久изация
Члены переменных, помеченные ключевым словом volatile, в каждый раз при доступе из-за границы вносят в себя значение из общей памяти. Более того, при изменении значения переменной,线程 вынужден записать измененное значение обратно в общую память. Таким образом, в каждый момент времени два различных потока всегда видят одинаковый результат для одной и той же переменной.
Ссылка на volatile объект может быть null.
public class MyRunnable implements Runnable { private volatile boolean active; public void run() { active = true; while (active) // Первый строке { // Код } } public void stop() { active = false; // Второй строке } }
Обычно в одном потоке вызывается метод run() (в线程, созданном с Runnable), в другом потоке вызывается метод stop(). Если Первый строке Если используется значение active в буфере, то в Второй строке Когда значение active равно false, цикл не остановится.
Но в этом коде мы используем модификатор volatile для active, поэтому этот цикл остановится.