Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

package vs. protected protection with Java reflection

Why can I use reflection to instantiate a inner protected class, but not an inner class with package-level protection? I wouldn't think either would be accessible outside the package.

Consider the following example:

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();
   }
}

Notice that the two classes are in different packages.

The first line in main (which instantiates InnerProtected) works.

The second line (which instantiates InnerDefault) throws this exception:

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

Since the driver is an a different package than the class definitions, shouldn't both attempts at instantiating the classes fail?

(For what it's worth: Attempting to instantiate InnerPrivate fails as I would expect:

Exception in thread "main" java.lang.InstantiationException: dummy.ClassContainer$InnerPrivate
like image 729
Zack Avatar asked Dec 16 '11 17:12

Zack


1 Answers

Really, javap reports that InnerProtected is compiled as public, whereas other member classes are package-private.

I believe it's caused by the need to make it visible to subclasses of ClassContainer from different packages. Perhaps VM cannot handle access control rules in this case, so that they are handled at compiler level.

Note, however, that if you omit constuctor declarations for these classes their generated constructors would have their expected visililities, that is protected, default and private respectively.

like image 173
axtavt Avatar answered Nov 15 '22 10:11

axtavt