Статьи

Справочное руководство по интервью с Java — часть 2

Модификатор доступа

Пожалуйста, обратитесь к Справочному руководству по  Java Interview — часть 1  для ознакомления с основными понятиями OOPS.
Модификатор доступа показывает, как другие классы обращаются к классу и его членам (методам и переменным.
Модификаторы доступа:

  • Закрытый: Закрытая переменная или метод (не внешний класс) может использоваться только экземпляром класса, который объявляет переменные или метод.
  • По умолчанию: данные класса и метод и сам класс могут быть по умолчанию. Функции класса по умолчанию доступны для любого класса в одном пакете.
  • Защищено: более доступно, чем по умолчанию. Только переменная и метод могут быть объявлены как защищенные. Защищенный объект класса доступен всем подклассам класса, которому принадлежат защищенные объекты. Этот доступ предоставляется даже для подклассов, которые находятся в другом пакете.
  • Public: открытый класс, переменная или метод могут использоваться для доступа к любой программе Java без каких-либо ограничений.

Замечания:

  • Единственным модификатором доступа, разрешенным для не внутреннего класса, является public, и не существует такого понятия, как защищенный или закрытый класс верхнего уровня.
  • Функция может иметь не более одного модификатора доступа. Если функция не имеет модификатора доступа, она получает доступ к режиму по умолчанию.
  • Конфиденциальность метода переопределена: метод не может быть переопределен, чтобы быть более закрытым.

В следующей таблице показан доступ к элементам, разрешенным каждым модификатором.

Снимок экрана 2014-06-02 в 2.00.05

Помимо базового модификатора доступа в таблице ниже представлены модификаторы в Java, которые также используются для изменения поведения класса и его членов, таких как метод, переменная, внутренние классы.

Модификаторы Java

Снимок экрана 2014-06-02 в 2.00.36 AM

Финал
Финальные изменения могут применяться к классу, методам и переменным, и это означает, что финальные характеристики не могут быть изменены. Например

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

Примечание. Если конечная переменная является ссылкой на объект, это должна быть та же ссылка, а не объект.

Статическая:

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

  • Статический метод: статические методы Java являются общими для классов и не привязаны к экземпляру Java. Статическому методу не разрешается использовать нестатические возможности своего класса, хотя они имеют свободный доступ к статическим данным и методу класса. Статический метод не может быть переопределен, чтобы быть нестатичным. Статические методы Java не могут использовать ключевое слово this.
  • Статический блок: блок статического кода выполняется только один раз при загрузке класса.
  • Статические переменные: переменным экземпляра Java предоставляется отдельная память для хранения. Если необходимо, чтобы переменная была общей для всех объектов одного Java-класса, то в объявлении переменной следует использовать статический модификатор. Любой объект Java, принадлежащий этому классу, может изменять свои статические переменные. Кроме того, экземпляр не является обязательным для изменения статической переменной, и к нему можно получить доступ напрямую с помощью класса java. Статические переменные могут быть доступны также с помощью методов экземпляра Java. Когда значение константы известно во время компиляции, оно объявляется как final с использованием ключевого слова static
  • Статический внутренний класс: только внутренний класс может быть объявлен с использованием статического модификатора и назван вложенными статическими классами в Java.

Внешние и внутренние классы (или вложенные классы)

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

Когда вы получаете доступ к закрытым членам данных внешнего класса, JDK-компилятор создает функции доступа к пакетам во внешнем классе, чтобы внутренний класс получил доступ к закрытым членам. Это оставляет дыру в безопасности. В общем, мы должны избегать использования внутренних классов.

Используйте внутренний класс только в том случае, если внутренний класс имеет значение только в контексте внешнего класса и / или внутренний класс может быть закрытым, так что только внешний класс может получить к нему доступ. Внутренние классы используются главным образом для реализации вспомогательных классов, таких как Итераторы, Компараторы и т. Д., Которые используются в контексте внешнего класса.

Разница между статическими и нестатическими вложенными классами

Нестатический вложенный класс (или «внутренний класс») имеет полный доступ к членам класса, в который он вложен. Статический вложенный класс не имеет ссылки на экземпляр вложенности, поэтому статический вложенный класс не может вызывать нестатические методы или обращаться к нестатическим полям экземпляра класса, в который он вложен.

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

Экземпляр нестатического внутреннего класса создается со ссылкой на объект внешнего класса, в котором он определен; это означает, что у него есть включающий экземпляр. Но экземпляр статического внутреннего класса создается без ссылки на класс Outer, что означает, что у него нет включающего экземпляра. Например.

Public Class OuterClass
{
Class InnerClass
{
// static int x; not allowed here
}
Static class StaticInnerClass
{
Static int x; // allowed here
}
}
Class Test
{
public static void main(String… str)
{
OuterClass oc=new OuterClass ();
OuterClass.InnerClass obj1 =oc.new InnerClass();//need of inclosing instance
OuterClass.StaticInnerClass obj2 =new OuterClass.SIC();
// no need of reference of object of outer class
}
}

Родной

Нативный модификатор может ссылаться только на методы. Нативные указывают, что тело метода должно быть найдено за пределами JVM.

Примечание: в случае абстрактных методов тело находится в подклассе с нативным методом, тело полностью находится вне виртуальной памяти Java, в библиотеке.

преходящий

Модификатор переходного процесса применяется только к переменной. Переходные переменные не сохраняются как часть постоянного состояния его объекта. Используйте для ключа безопасности, подключения и т. Д., Что не требуется для поиска.

синхронизированный

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

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

Во-вторых, при выходе из синхронизированного метода он автоматически устанавливает отношение «до и после» с любым последующим вызовом синхронизированного метода для того же объекта. Это гарантирует, что изменения состояния объекта видны всем потокам.

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

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

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

Когда поток вошел в метод синхронизированного экземпляра, никакой другой поток не может ввести ни один из методов синхронизированного экземпляра того же экземпляра.

Когда поток входит в синхронизированный статический метод, никакой другой поток не может войти ни в один из синхронизированных статических методов того же класса

Примечание. Отсутствует связь между синхронизированными статическими методами и синхронизированными нестатическими методами, т. Е. Если статический метод синхронизации и нестатический метод синхронизации могут запускать метод одновременно, если только нестатический метод не должен явно синхронизироваться с самим классом (т. Е. Синхронизирован (MyClass.class ) {…}

летучий

Только переменная может быть изменчивой. Такая переменная может быть изменена асинхронно, поэтому компилятор принимает особые меры предосторожности. Модификатор volatile гарантирует, что любой поток, который читает поле, увидит последнее записанное значение.

Использование volatile.  Одним из распространенных примеров использования volatile является использование логической переменной volatile в качестве флага для завершения потока.

Разница между Volatile и Synchronize:

Поэтому, когда volatile только синхронизирует значение одной переменной между памятью потоков и «основной» памятью, синхронизированный синхронизирует значение всех переменных между памятью потоков и «основной» памятью, а также блокирует и освобождает монитор для загрузки. Четкая синхронизация, вероятно, будет иметь больше накладных расходов, чем энергозависимых.

Изменчивая переменная не может иметь локальную копию переменной, которая отличается от значения, которое в настоящее время хранится в «основной» памяти.

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

Аннотация

Модификатор abstract может применяться к классу и методам. Класс, который является абстрактным, может не быть экземпляром и должен быть расширен для оценки. Резюме не может быть применимо к переменным членам класса

Пример : у класса животных есть метод перемещения, и у каждого подкласса (змея, собака, птица) свой путь передвижения. Таким образом, невозможно обеспечить travel () в суперклассе. Вместо этого суперкласс Animal объявляет travel () абстрактным.

Замечания:

  • Если класс содержит еще один абстрактный метод, компилятор настаивает на том, чтобы класс был объявлен абстрактным.
  • Аннотация против финала. Последний класс не может быть подклассами; абстрактный класс должен быть подклассом.

В дизайне вы хотите, чтобы базовый класс представлял только интерфейс для его производных классов. Это означает, что вы не хотите, чтобы кто-либо на самом деле создавал объект базового класса. Вам нужно только выполнить приведение к нему (неявное приведение, которое дает вам полиморфное поведение), чтобы можно было использовать его интерфейс. Это достигается тем, что этот класс является абстрактным с использованием ключевого слова abstract.

Предоставьте некоторое ограничение, чтобы не создавать экземпляр абстрактного класса, и тот, кто использует, должен реализовывать абстрактный метод. И обеспечить полиморфизм.

Когда использовать абстрактный класс?

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

Например:  внедрение зависимостей среды Spring продвигает код в абстрактную реализацию принципа интерфейса в рамках коллекции.