Рубрики
Без рубрики

Модификатор “публичного” доступа Java

Узнайте, как лучше всего использовать модификатор “публичного” доступа Java

Автор оригинала: baeldung.

1. Обзор

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

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

Для общего обзора модификаторов доступа обязательно ознакомьтесь с нашей статьей о Модификаторах доступа в Java .

2. Когда следует использовать Модификатор публичного доступа

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

Однако чрезмерное использование модификатора public нарушает принцип инкапсуляции Объектно-ориентированного программирования (ООП) и имеет несколько недостатков:

  • Это увеличивает размер API, усложняя его использование клиентами
  • Становится все труднее изменять наш код, потому что клиенты полагаются на него — любые будущие изменения могут привести к нарушению их кода

3. Общедоступные интерфейсы и классы

3.1. Общедоступные Интерфейсы

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

Например, Java API предоставляет интерфейс Connection для определения операций подключения к базе данных, оставляя фактическую реализацию каждому поставщику. Во время выполнения мы получаем желаемое соединение на основе настроек проекта:

Connection connection = DriverManager.getConnection(url);

Метод getConnection возвращает экземпляр реализации, зависящей от конкретной технологии.

3.2. Публичные Занятия

Мы определяем общедоступные классы, чтобы клиенты могли использовать их члены путем создания экземпляров и статических ссылок:

assertEquals(0, new BigDecimal(0).intValue()); // instance member
assertEquals(2147483647, Integer.MAX_VALUE); // static member

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

Например, платформа коллекций Java предоставляет класс AbstractList в качестве основы для создания настраиваемых списков:

public class ListOfThree extends AbstractList {

    @Override
    public E get(int index) {
        //custom implementation
    }

    @Override
    public int size() {
        //custom implementation
    }

}

Таким образом, нам нужно только реализовать методы get() и size () . Другие методы, такие как indexOf() и содержит все () , уже реализованы для нас.

3.3. Вложенные общедоступные классы и интерфейсы

Подобно общедоступным классам и интерфейсам верхнего уровня, вложенные общедоступные классы и интерфейсы определяют тип данных API. Однако они особенно полезны в двух отношениях:

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

Примером может служить Карта . Запись интерфейс из основного Java API:

for (Map.Entry entry : mapObject.entrySet()) { }

Составление Карты . Запись вложенный интерфейс сильно связывает его с java.util.Карта интерфейс и спас нас от создания другого файла внутри пакета java.util .

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

4. Публичные Методы

Общедоступные методы позволяют пользователям выполнять готовые операции. Примером может служить открытый toLowerCase метод в String API:

assertEquals("alex", "ALEX".toLowerCase());

Мы можем безопасно сделать общедоступный метод статичным, если он не использует никаких полей экземпляра. Метод parseInt из класса Integer является примером общедоступного статического метода:

assertEquals(1, Integer.parseInt("1"));

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

5. Публичные Поля

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

5.1. Безопасность резьбы

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

Пожалуйста, ознакомьтесь с нашей статьей о потокобезопасности, чтобы узнать больше о написании потокобезопасного кода.

5.2. Принятие мер по внесению изменений

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

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

public class Student {

    private int age;
    
    public void setAge(int age) {
        if (age < 0 || age > 150) {
            throw new IllegalArgumentException();
        }
    
        this.age = age;
    }
}

5.3. Изменение типа данных

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

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

    
public class Student {

    private StudentGrade grade; //new data representation
   
    public void setGrade(int grade) {        
        this.grade = new StudentGrade(grade);
    }

    public int getGrade() {
        return this.grade.getGrade().intValue();
    }
}

Единственным исключением для использования общедоступных полей является использование статических конечных неизменяемых полей для представления констант:

public static final String SLASH = "/";

6. Заключение

В этом уроке мы увидели, что модификатор public используется для определения API.

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

Наконец, мы обсудили, почему использовать общедоступные модификаторы для полей-плохая практика.

И, как всегда, примеры кода этой статьи доступны на GitHub .