Вопрос-ответ

Why can outer Java classes access inner class private members?

Почему внешние классы Java могут получать доступ к закрытым членам внутреннего класса?

Я заметил, что внешние классы могут получать доступ к закрытым переменным экземпляра внутреннего класса. Как это возможно? Вот пример кода, демонстрирующий то же самое:

class ABC{
class XYZ{
private int x=10;
}

public static void main(String... args){
ABC.XYZ xx = new ABC().new XYZ();
System.out.println("Hello :: "+xx.x); ///Why is this allowed??
}
}

Почему такое поведение разрешено?

Переведено автоматически
Ответ 1

Внутренний класс - это просто способ четко разделить некоторые функциональные возможности, которые действительно принадлежат исходному внешнему классу. Они предназначены для использования, когда у вас есть 2 требования:


  1. Некоторые функциональные возможности вашего внешнего класса были бы наиболее понятны, если бы они были реализованы в отдельном классе.

  2. Несмотря на то, что это отдельный класс, функциональность очень тесно связана с тем, как работает внешний класс.

Учитывая эти требования, внутренние классы имеют полный доступ к своему внешнему классу. Поскольку они в основном являются членами внешнего класса, имеет смысл, что у них есть доступ к методам и атрибутам внешнего класса, включая закрытые.

Ответ 2

Если вы хотите скрыть закрытые члены вашего внутреннего класса, вы можете определить интерфейс с открытыми членами и создать анонимный внутренний класс, который реализует этот интерфейс. Пример ниже:

class ABC{
private interface MyInterface{
void printInt();
}

private static MyInterface mMember = new MyInterface(){
private int x=10;

public void printInt(){
System.out.println(String.valueOf(x));
}
};

public static void main(String... args){
System.out.println("Hello :: "+mMember.x); ///not allowed
mMember.printInt(); // allowed
}
}
Ответ 3

The inner class is (for purposes of access control) considered to be part of the containing class. This means full access to all privates.

The way this is implemented is using synthetic package-protected methods: The inner class will be compiled to a separate class in the same package (ABC$XYZ). The JVM does not support this level of isolation directly, so that at the bytecode-level ABC$XYZ will have package-protected methods that the outer class uses to get to the private methods/fields.

Ответ 4

There's a correct answer appearing on another question similar to this:
Why can the private member of an nested class be accessed by the methods of the enclosing class?

It says there's a definition of private scoping on JLS - Determining Accessibility:


Otherwise, if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.


java class