IllegalAccessError: доступ к защищенному методу

У меня есть два класса.

Класс A имеет защищенный метод m(), A - это экземпляр A.

Класс B находится в том же пакете, что и класс A.

Я пытаюсь получить доступ к a.m(), но я получаю IllegalAccessError...

Что не так?

Ответ 1

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

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

Ответ 2

Это может произойти, если классы A и B загружаются разными загрузчиками классов. Затем jvm рассматривает эти классы в разных "пакетах времени выполнения". Цитата из спецификация jvm, раздел 5.3:

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

И в разделе 5.4.4:

Поле или метод R доступно для класса или интерфейса D тогда и только тогда, когда выполняется одно из следующих условий:

...

R является либо защищенным, либо закрытым пакетом (то есть ни открытым, ни защищенным, ни закрытым) и объявляется классом в том же пакете времени выполнения, что и D.

Ответ 3

Он должен работать, см. следующий пример, который работает очень хорошо:

package com.stackoverflow;

public class TEST
{
  static class A {
    protected void m()
    {
      System.out.println("hello from A.m()");
    }
  }

  static class B {

    public B()
    {
      a.m();
    }

    private A a = new A();
  }

  /**
   * @param args
   */
  public static void main(String[] args)
  {
    B b = new B();
  }
}

который печатает сообщение: "hello from A.m()"

"Защищенный модификатор указывает, что член может быть доступен только внутри его собственный пакет (как с пакет-частный) и, кроме того, подкласс его класса в другом пакет".

См. Управление доступом к членам класса.

Ответ 4

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

Он должен работать. Вот пример:

**

  • КЛАСС А

**

package com.test;

public class A {

  protected void m(){
  System.out.println("Hi Stackoverflow");
 }

}

**

  • КЛАСС B

**

package com.test;

public class B{

public static void main(String[] args) {
  A a = new A();
  a.m();
 }

}

который печатает ожидаемую строку

Привет, Stackoverflow