Модификаторы в Java: static, final, abstract, synchronized, transient, volatile.

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

Модификаторы в Java – это ключевые слова, которые придают классу, полю класса или методу определенные свойства.

Для обозначения видимости класса его методов и полей есть 4 модификатора доступа:

  • private члены класса доступны только внутри класса;
  • package-private или default (по умолчанию) члены класса видны внутри пакета;
  • protected члены класса доступны внутри пакета и в классах-наследниках;
  • public члены класса доступны всем.

Если Вы помните прошлую статью, то в конце, когда мы уже импортировали класс Cat, у нас все равно была ошибка компиляции.

Код    
  1. package com.cat; //заметьте, появилась новая строка объявления пакета
  2.  
  3. public class Cat {
  4.  
  5.     String color;
  6.     int weight;
  7.     String sex;
  8.     char s;
  9.     double v;
  10.     float g;
  11.     boolean b;
  12.  
  13.      Cat() {//конструктор без параметров
  14.         //сюда можно писать код, который будет выполняться при создании объекта
  15.     }
  16.  
  17.      Cat(String catsColor){//конструктор с одним параметром
  18.          color = catsColor;
  19.      }
  20.  
  21.      Cat(String catsColor, int catsWeight, String catsSex){//конструктор с тремя параметрами
  22.          color = catsColor;
  23.          weight = catsWeight;
  24.          sex = catsSex;
  25.      }
  26.  
  27.     void myaukat(int count){
  28.         for (int i = 0; i < count; i++) {
  29.             System.out.println("Meaou!");
  30.         }
  31.     }
  32.  
  33.     void walk(){
  34.         System.out.println("Char " + s);
  35.         System.out.println(v);
  36.         System.out.println(g);
  37.         System.out.println(b);
  38.  
  39.     }
  40.  
  41.     String methodForEveryObject(){
  42.  
  43.         return color + " cat is walking";
  44.     }
  45.  
  46. }

 

изменить модификаторы

Все дело в том, что мы не прописали никаких модификаторов доступа к нашим полям и методам и они имеют свойство по умолчанию (члены класса видны внутри пакета). Чтобы исправить ошибку компиляции для нашего кода и наконец то запустить его, нужно сделать наш конструктор и методы public. Тогда их можно будет вызывать с других пакетов.

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

Представьте, что у Вас есть класс который отображает объект некоего продукта. Например машина. У машины может быть цена. Вы создали поле цена и еще множество других полей, кучу методов которые отвечают за функционал. Все вроде хорошо. Ваш класс машина является частью огромного проекта и все довольны. Но допустим, что кто-то по ошибке или специально создал экземпляр класса автомобиль и поставил отрицательную цену. Разве может товар иметь отрицательную цену? Это очень примитивный пример и вряд ли такое может случиться в реальной жизни, но думаю, идея понятна. Иногда нужно дать доступ не напрямую, а через определенные методы. Может быть, что код отвечает за функционал другого кода, и Вы не хотите, чтобы кто-то изменял и редактировал часть Вашего. Для этого всего и есть ограничение доступа.

Модификатор доступа у конструкторов, методов и полей может быть любой. Класс может быть только либо public, либо default, причем в одном файле может находиться только один public класс. только один паблик класс

Пока об модификаторах доступа будет достаточно. В статье «Объектно ориентированное программирование» мы о них поговорим подробнее, а сейчас давайте поговорим о других модификаторах которых, к стати, немало.

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

static модификатор перед методом или полем говорит о том, что они не принадлежат к экземпляру данного класса. Что это означает для нас? Когда мы описали поле класса или метод как static, его можно вызвать без использования экземпляра класса. То есть вместо такой конструкции: Cat cat = new Cat(); cat.method(), можно написать просто Cat.method(). При условии, что метод объявлен как static. Статические переменные едины для всех объектов класса. У них одна ссылка.

Код    
  1. public class Modificators {
  2.    
  3.     static String someField;
  4.     static int anotherStaticField = 5;
  5.     String nonStaticField;
  6.    
  7.     public static void myStaticMethod(){
  8.         someField = "My field";
  9.         //nonStaticField = ""; ошибка компиляции
  10.         //нельзя использовать нестатические поля
  11.         //в статических методах
  12.     }
  13.    
  14.     public void myNonStaticMethod(){
  15.         anotherStaticField = 4;//ститические поля можно использовать
  16.         //в нестатических методах
  17.     }
  18.    
  19.     public static void main(String[] args){//обратите внимание,
  20.         //main метод тоже имеет модификатор static
  21.         System.out.println(Modificators.anotherStaticField);//5
  22.         new Modificators().myNonStaticMethod();
  23.         System.out.println(Modificators.anotherStaticField);//4
  24.         Modificators.myStaticMethod();//вызов статических методов и полей
  25.         //через имяКласса.метод
  26.        
  27.     }
  28.  
  29. }

 

Еще одно важное замечание, которое нужно сказать по поводу static модификаторов: статические поля инициализируются во время загрузки класса. Часто в разного рода тестах по Java можно встретить такой код: 

Код    
  1. public class OftenQuestions {
  2.    
  3.     {
  4.         System.out.println(1);
  5.     }
  6.    
  7.     static {
  8.         System.out.println(2);
  9.     }
  10.    
  11.     public OftenQuestions() {
  12.         System.out.println(3);
  13.     }
  14.    
  15.     public void myMethod(){
  16.         System.out.println(4);
  17.     }
  18.  
  19.     public static void main(String[] args) {
  20.         System.out.println(5);
  21.         OftenQuestions o = new OftenQuestions();
  22.         o.myMethod();
  23.  
  24.     }
  25.  
  26. }

 

Вопрос: что будет выведено на консоль? Нужно помнить, что static блок будет выведен первым при любом раскладе. Далее будет идти блок по умолчанию. Далее смотрите на скрин консоли:часто задаваемые вопросы

 

Следующий модификатор, который мы рассмотрим будет final. 

Думаю, слово final говорит само за себя. Применяя final модификатор Вы говорите, что поля не могут быть изменены, методы переопределены, а классы нельзя наследовать (о наследовании будет отдельная статья). Этот модификатор применяется только к классам, методам и переменным (также и к локальным переменным).

Код    
  1. public final class FinalModificator {
  2.    
  3.     final static String CONSTANT = "Hi there";//полю CONSTANT нельзя дать новое значение
  4.     //таким образом в джаве можно объявлять константы.
  5.     //константы в языке Java обычно пишут в верхнем регистре
  6.    
  7.     final int ANOTHER_CONSTANT;
  8.     //константы нужно инициализировать при объявлении или в конструкторе.
  9.    
  10.    
  11.  
  12.     public static void main(String[] args) {
  13.         // TODO Auto-generated method stub
  14.         FinalModificator.CONSTANT = "Bue there";//ошибка компиляции
  15.         //попытка переопределить константу
  16.        
  17.     }
  18.  
  19. }

 

С модификатором final к методам и классам мы будем говорить в статье ООП.

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

Модификатор synchronized — говорит о том, что метод может быть использован только одним потоком одновременно. Хотя, возможно, это Вам ни о чем не говорит, полезность этого модификатора будет видно, когда мы будем изучать многопоточность.

Модификатор transient — говорит о том, что во время сериализации объекта некоторое поле нужно игнорировать. Как правило, такие поля хранят промежуточные значения.

Модификатор volatile — используется при многопоточности. Когда поле с модификатором volatile будет использоваться и изменяться несколькими потоками, данный модификатор гарантирует, что поле будет изменяться по очереди и путаницы с ним не возникнет.

Модификатор native перед объявлением метода указывает что метод написан на другом языке программирования. Обычно на языке C.

Модификатор strictfp — Обеспечивает выполнение операций над числами типа float и double (с плавающей запятой) по стандарту IEEE 754. Или говоря проще, гарантирует что в  пределах метода результаты вычислений будут одинаковыми на всех платформах.

Я еще не говорил о модификаторе abstract. О нем скажу вкратце, так как без знаний основ объектно ориентированного программирования говорить о нем не вижу смысла.

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

Подробнее о модификаторе abstract будем говорить в статье ООП.

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

Добавить комментарий