Доступ к закрытому внутреннему классу в том же пакете - PullRequest
11 голосов
/ 10 мая 2011

У меня есть два блока компиляции:

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, даже если он находится в том же пакете.Я что-то не так понимаю?

Ответы [ 2 ]

8 голосов
/ 10 мая 2011

Подпись javap для внутреннего класса:

class modifiers.OuterClass$InnerClass extends java.lang.Object{
    final modifiers.OuterClass this$0;
    public java.lang.String test();
}

Когда дело касается байт-кода (т. Е. Времени выполнения), такого понятия, как закрытый класс, не существует.Это фикция, поддерживаемая компилятором.Для API-рефлексии существует доступный для пакета тип с открытым методом члена.

Фактические модификаторы доступа определены в JVM spec :

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. 
0 голосов
/ 10 мая 2011

Модификатор закрытого доступа сильнее, чем первый пакет (т.е. вообще не имеет модификатора доступа в Java). Следовательно, частные элементы класса - будь то поля, методы или внутренние классы - доступны только внутри этого класса.

...