пакет против защищенной защиты с отражением Java - PullRequest
7 голосов
/ 16 декабря 2011

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

Рассмотрим следующий пример:

package dummy;

public class ClassContainer {
   protected static class InnerProtected {
      public InnerProtected() {}
   }

   static class InnerDefault {
      public InnerDefault() {}
   }

   private class InnerPrivate {
      public InnerPrivate() {}
   }
}


package driver;

public class DriverClass {

   public static void main(String[] args) throws Exception {
      Class.forName("dummy.ClassContainer$InnerProtected").newInstance();
      Class.forName("dummy.ClassContainer$InnerDefault").newInstance();
      Class.forName("dummy.ClassContainer$InnerPrivate").newInstance();
   }
}

Обратите внимание, что два класса находятся в разных пакетах.

первая строка в main (которая создает экземпляр InnerProtected) работает.

вторая строка (которая создает экземпляр InnerDefault) выдает это исключение:

Exception in thread "main" java.lang.IllegalAccessException: Class driver.DriverClass can not access a member of class dummy.ClassContainer$InnerDefault with modifiers "public"

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

(Для чего стоит: попытка создания экземпляра InnerPrivate терпит неудачу, как я и ожидал:

Exception in thread "main" java.lang.InstantiationException: dummy.ClassContainer$InnerPrivate

1 Ответ

4 голосов
/ 16 декабря 2011

Действительно, javap сообщает, что InnerProtected скомпилировано как public, тогда как другие классы-члены являются пакетно-закрытыми.

Я полагаю, что это вызвано необходимостью сделать его видимым для подклассов ClassContainer из разных пакетов. Возможно, в этом случае VM не сможет обработать правила контроля доступа, поэтому они обрабатываются на уровне компилятора.

Обратите внимание, однако, что если вы опустите объявления конструкторов для этих классов, их сгенерированные конструкторы будут иметь ожидаемую видимость, то есть protected, по умолчанию и private соответственно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...