0

In my example I have two packages: package1 contains class A (NOT declared as public) and its nested static class B (declared as public):

package package1;    
class A {
    public static class B {
        public B() {
        }
    }
    public A() {
    }    
}

package2 contains a Main class with a simple main method that tries to reflectively create an instance of class package1.A$B:

package package2;       
public class Main {    
    public static void main(String[] args) {
        try {
            Class<?> innerClass = Class.forName("package1.A$B");
            Object o = innerClass.newInstance();
            System.out.println(o);
        } catch (ReflectiveOperationException e) {
            e.printStackTrace();
        }
    }    
}

Surprisingly (at least for me), this piece of code succeeds in doing something otherwise impossible without reflection. Classic import statements (like import package1.A.B; or import package1.A.*;) raise errors arguing that class A is not visible. Moreover, there is no need to require special accessibility priviledges to create the instance of B. Is it a normal behaviour?

EDIT: It works also if I get a reference to the inner class in a different way, like this:

Class<?> innerClass = Class.forName("package1.A").getClasses()[0];
maurizeio
  • 266
  • 2
  • 11

1 Answers1

0

yes, this is a absolutely fine. When you write like package.classname$innerclass, you can get the static innerclass.

Vineet Singla
  • 1,609
  • 2
  • 20
  • 34
  • ok but in this case I was expecting a `java.lang.IllegalAccessException` at construction – maurizeio Apr 30 '13 at 09:45
  • An IllegalAccessException is thrown when an application tries to reflectively create an instance (other than an array), set or get a field, or invoke a method, but the currently executing method does not have access to the definition of the specified class, field, method or constructor. Class B is public and static and easily accessible – Vineet Singla Apr 30 '13 at 09:48
  • ok, but if it's legal to access class B because it's public, why is it impossible to directly import class `package1.A.B`? – maurizeio Apr 30 '13 at 09:59
  • 2
    Here comes, the concept of ClassLoaders. Let me try to explain : See when you do import class package1.A.B, it tries to search for that class at compile time , but the class is not visible and gives the error. But when you do Class.forName - it goes to the class loader with String value(which is a fully qualified class name). and looks for that class in classloader which it has and therefore successfully returned. – Vineet Singla Apr 30 '13 at 10:04