Given the code example below, why does
theAnswer.get( outer )
Exception in thread "main" java.lang.IllegalAccessException: Class Outer$Inner can not access a member of class Outer with modifiers "private"
public class Outer
private int theAnswer = 42;
public static class Inner
public void accessDirectly( Outer outer )
System.out.println( outer.theAnswer );
public void accessUsingReflection( Outer outer ) throws NoSuchFieldException,
Field theAnswer = Outer.class.getDeclaredField( "theAnswer" );
// Of course, uncommenting the next line will make the access using reflection work.
// field.setAccessible( true );
System.out.println( theAnswer.get( outer ) );
public static void main( String args ) throws NoSuchFieldException,
Outer outer = new Outer();
Inner inner = new Inner();
inner.accessDirectly( outer );
inner.accessUsingReflection( outer );
"Why" questions like these can tricky to answer - there are many layers of "why", including why did the designers choose to do this? what part of the specification allows this? what are the underlying technical details?
I'll answer the last of those, but I'm not sure if that's what you're after.
The Java runtime (JVM, security model, etc) is largely ignorant about inner classes. They are, for the most part, a language issue.
One of the consequences of that is that compiler uses some hidden tricks to allow inner/outer classes to access each other's private members, even though the runtime would not ordinarily allow it.
One of those tricks is that your
accessDirectly method is not actually accessing the field directly. The compiler adds a hidden method onto the outer classes that returns the value of
The field (
theAnswer) is still private, and as far as the runtime security model is concerned, cannot be accessed outside of the owning (outer) class.
Thus, there are things that you can (seemingly) do in Java code that you can't do with reflection because they rely on special behaviours in the compiler that are not replicated in the reflection library.
You can read more here