ПрограммированиеJava разработчик

Опишите, как работает модификатор доступа protected в Java, в чём его отличие от других модификаторов, и какие ошибки допускаются при его неправильном понимании.

Проходите собеседования с ИИ помощником Hintsage

Ответ.

Модификатор доступа protected позволяет членам класса быть видимыми внутри того же пакета (package) и во всех подклассах (subclasses), даже если они находятся в других пакетах.

Различия c другими модификаторами:

  • private — доступ только в пределах текущего класса
  • default (без модификатора) — доступен только внутри текущего пакета
  • protected — доступен внутри текущего пакета и в наследниках вне пакета
  • public — доступен везде

Пример:

package com.example.base; public class Parent { protected void sayHello() { System.out.println("Hello from parent"); } } package com.example.child; import com.example.base.Parent; public class Child extends Parent { public void tryHello() { sayHello(); // Доступ есть! } } public class NotChild { public void fail(Parent p) { // p.sayHello(); // Ошибка: нет доступа } }

Вопрос с подвохом.

Может ли внешний класс (не являющийся наследником) получить доступ к protected-методу из другого пакета, имея объект этого класса?

Ответ: Нет, доступ к protected-методу из другого пакета разрешён только классам-наследникам, и только через this или через ссылку на объект-наследник, а не на родителя.

Parent p = new Child(); p.sayHello(); // Ошибка! ((Child) p).sayHello(); // Успех (если обращается внутри Child)

Примеры реальных ошибок из-за незнания тонкостей темы.


История

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


История

В проекте микросервисов метод с protected-доступом пытались вызывать по ссылке на тип родителя в другом пакете — вызов не работал. Это вызвало сбой в части механизмов расширения системы, потому что полагались на некорректное понимание области видимости.


История

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