Также в Java предусмотрены 4 других (non-access) модификатора:
- final
Делает переменную, метод или класс финальным (неизменяемым). - static
Используется для создания методов и переменных - abstract
Используется для создания абстрактных классов. - synchronized
Используется в многопоточном программировании. - volatile
Используется в многопоточном программировании
- transient
Используется для пропуска переменной во время её сериализации.
Давайте рассмотрим каждый из них отдельно.
final
Метод c модификатором final не может быть перезаписан любым подклассом. Финальные методы и переменные не могут быть изменены.
Пример
public class Company {
public final void showCompanyDirector(){
System.out.println("Company director is Ivan Ivanov for all times.");
}
}
Если же мы объявляем класс, как final, то мы не можем от него наследоваться.
Пример:
public final class SecretClass {
private String secretInfo;
//some other fields and methods...
}
static
Статические переменные
Если переменная класса объявлена, как статическая, то она будет существовать независимо от экземпляров данного класса. Существует одна копия статической переменной независимо от количества экземпляров.
Локальные переменные не могут быть статическими.
Статические методы
Если метод класса объявлен, как статический, то он будет существовать независимо от экземпляров данного класса. Существует одна копия статического метода независимо от количества экземпляров.
Статические методы не используют никакие переменные, объявленные в классе, в котором эти методы созданы.
Вызов статического метода происходит написанием самого метода, а не в виде:
экземпляр_класса.статический_метод()
Пример:
package net.proselyte.javacore.modifiers.nonaccess;
public class CarFactory {
private static int carAmount = 0;
private static int getCarAmount() {
return carAmount;
}
private static void buildCar() {
carAmount++;
}
public CarFactory() {
CarFactory.buildCar();
}
public static void main(String[] args) {
System.out.println("Before working day on factory there is: " + getCarAmount() + " cars.");
for (int i = 0; i < 10; i++) {
new CarFactory();
}
System.out.println("After one working day on factory there are: " + getCarAmount() + " cars.");
}
}
В результате работы программы мы получим следующий результат:
/*Some system messages*/
Before working day on factory there is: 0 cars.
After one working day on factory there are: 10 cars.
abstract
Абстрактный класс
Абстрактный класс – это класс, который не имеет экземпляра. Если мы создаём абстрактный класс, то его назначение состоит в том, чтобы от него наследовались другие классы.
Абстрактный класс не может иметь модификатор final.
Если класс содержит абстрактные методы, то он должен быть объявлен, как абстрактный.
Пример:
package net.proselyte.javacore.modifiers.nonaccess.abstractclasses;
public abstract class Beast {
private String beastName;
public Beast(String beastName) {
this.beastName = beastName;
}
public abstract void toBreath();
public abstract void toEat();
}
Здесь мы видим абстрактный класс Beast (зверь). Есть понятие зверь, но нет такого животного под названием зверь. Поэтому это прекрасный пример для абстрактного класса.
Абстрактный метод
Абстрактный метод – это метод, который объявлен, но не реализован, т.е. не имеющий внутри никакой логики. Классы наследники абстрактного класса будут имплементировать этот метод.
Любой класс, который наследует абстрактный класс должен имплементировать все его абстрактные методы. За исключением случая, когда класс – наследник также является абстрактным классом.
Абстрактный класс необязательно должен содержать абстрактные методы.
Рассмотрим пример.
Выше мы уже привели пример класса Beast, а теперь мы создадим класс, который будет наследоваться от него.
Все звери как-то едят и как-то дышат, каждый по-своему, но у всех есть такое поведение.
Рассмотрим класс Cat (Кот), который является частным случаем зверя.
package net.proselyte.javacore.modifiers.nonaccess.abstractclasses;
public class Cat extends Beast{
private String color;
public Cat(String beastName) {
super(beastName);
}
@Override
public void toBreath() {
System.out.println("Cat uses lungs for breathing");
}
@Override
public void toEat() {
System.out.println("Cat eats fish.");
}
}
Как мы видим, в методах toBreath() и toEat() мы конкретизируем, что кот дышит используя лёгкие, а ест рыбу.
synchronized
Модификатор synchronized говорит о том, что данный метод может быть задействован только одним потоком одновременно.
Пример:
public synchronized void showCompanyName(){
System.out.println("Company name is SkybleSoft.");
}
volatile
Модификатор volatile используется для того, чтобы указать JVM, что поток, который обращается к переменной должен всегда сливать (merge) свою собственную копию переменной с главной копией в памяти0.
Обращение к волатильной переменной синхронизирует все кешированные копии переменной в памяти. Модификатор volatile может применяться только к переменным.
Пример
package net.proselyte.javacore.modifiers.nonaccess.volatilemodifier;
public class Transaction implements Runnable{
private volatile boolean isActive;
@Override
public void run() {
isActive = true;
while (isActive){
System.out.println("Transaction is active...");
}
}
public void stop(){
isActive = false;
System.out.println("Transaction stopped.");
}
}
В этом примере у нас есть некая транзакция, которая активизируется методом run() и прекращается вызовом метода stop().
transient
Модификатор transient даёт команду JVM пропустить данную переменную во время сериализации содержащего её объекта.
Пример:
public transient String remarks = "Some remarks."; //This variable will not be resisted
public transient String name; //This variable will be persisted.
В этом примере переменная remarks (примечания) не будет сохранена, а переменная name (имя) – будет.
В этой статье мы рассмотрели другие (non-access) модификаторы.