打破Java中的封装和信息隐藏

打破Java中的封装和信息隐藏,java,oop,inheritance,encapsulation,information-hiding,Java,Oop,Inheritance,Encapsulation,Information Hiding,考虑以下代码段 package breakoop; public class BreakOOP { public static class A{ private int a; } public static class B extends A{ public int f(){ return super.a; } } public static void main(String[

考虑以下代码段

package breakoop;

public class BreakOOP {

    public static class A{
        private int a;
    }

    public static class B extends A{
        public int f(){
            return super.a;
        }
    }

    public static void main(String[] args) {
        B b = new B();
        System.out.println(b.f());
    }
}
该示例仅在
A
B
封装在
breakop
类中时编译

这似乎违背了OOP的一些基本概念。有人能解释一下为什么会这样编译吗?这背后的原因是什么?

请检查以下内容:。它说它通过允许静态类访问顶级类的私有成员(有时您可能需要这样做)来增加封装。而
类的私有成员,属于
的范围,这反过来又使它可以在类
B
中访问。这些州:

私有类成员或构造函数只能在包含成员或构造函数声明的顶级类(§7.6)的主体内访问

由于类
A
B
是在
breakop
的主体中定义的,因此该规则适用,
B
可以看到
A
的私有成员


至于OOP概念:由于
A
B
是静态的内部类,它们与
breakop
没有真正的内部类所具有的特殊生命周期关系(也就是说,创建
a
B
的新实例时,您不需要使用
breakop
的实例,但它们仍然具有某种特殊的关系,因为它们可以访问私有成员。如果它们不应该具有这种关系,那么它们不应该是内部类,而应该是真正的顶级类。

您指的是
super.a
我想是吧。之所以编译,是因为规范中这么说,即在顶级类的范围内,即在您的情况下,
breakop
内,任何私有成员都是可见的(我必须查找JLS的相关部分).内部类从它们的父类中获取可见性规则。为什么会这样?-有待讨论,这只是java中的方式。因此,从B访问super.a就像Breakop类中的两个私有变量。如果你想要更广泛的保护,你必须将它们移到不同的编译单元中。我不知道这可能是重复的这是为什么允许的,但是它增加封装的论点,在我看来,类似于为什么C++中的朋友关键字可以增加封装的争论。为什么你认为它不应该编译?