Доступ к закрытому внутреннему классу в одном пакете
У меня есть две единицы компиляции:
public class OuterClass{
private static class InnerClass{
public String test(){
return "testing123";
}
}
public static void main( String[] args ){
new CallingClass().test( new InnerClass() );
}
}
public class CallingClass{
public void test( Object o ){
try{
Method m = o.getClass().getMethod( "test" );
Object response = m.invoke( o );
System.out.println( "response: " + response );
}
catch( Exception e ){
e.printStackTrace();
}
}
}
Если они находятся в одном пакете, все работает и печатается "response: testing123". Если они находятся в отдельных пакетах, выбрасывается исключение IllegalAccessException.
Как я понимаю, исключение вызывается, потому что CallingClass не может вызывать частные методы InnerClass. Но я не понимаю, почему это разрешено в одном пакете? InnerClass не защищен пакетом. Частный не должен быть видимым вне OuterClass, даже если он находится в одном пакете. Я понимаю что-то не так?
Ответы
Ответ 1
javap подпись для внутреннего класса:
class modifiers.OuterClass$InnerClass extends java.lang.Object{
final modifiers.OuterClass this$0;
public java.lang.String test();
}
Когда дело доходит до байт-кода (т.е. время выполнения), нет такой вещи, как частный класс. Это выдумка, поддерживаемая компилятором. В API отражения есть доступный для пакета тип с общедоступным методом-членом.
Действительные модификаторы доступа определены в спецификации JVM:
Flag Name Value Interpretation
ACC_PUBLIC 0x0001 Declared public; may be accessed from outside its package.
ACC_FINAL 0x0010 Declared final; no subclasses allowed.
ACC_SUPER 0x0020 Treat superclass methods specially when invoked by the
invokespecial instruction.
ACC_INTERFACE 0x0200 Is an interface, not a class.
ACC_ABSTRACT 0x0400 Declared abstract; may not be instantiated.
Ответ 2
Частный модификатор доступа сильнее, чем один пакет (т.е. вообще не имеет модификатора доступа на Java). Следовательно, частные элементы класса - будь то поля, методы или внутренние классы - доступны только внутри этого класса.