繁体   English   中英

内部类中私有变量的范围

[英]Scope of private variables within inner classes

考虑以下代码:

public class Foo
{
    class Bar
    {
        private String barbar;

        public Bar( String b ) { barbar = b; }
    }

    class Meh
    {
        Bar b = new Bar("BAR!");

        public void displayName() {
            System.out.println( b.barbar );
        }    
    }
}

Java 允许Meh类访问私有实例变量barbar ,该变量在Bar中被声明为private

我知道这个问题在这里之前已经被问过。 但是,答案基本上只是重申了观察到的范围就是它的样子(在类Foo的大括号中可以访问barbar ),但没有提供任何解释。 在谷歌搜索之后,我无法很好地讨论这种行为。 我想知道的是,这种范围界定行为是否有特定的理由。 我本来希望barbar在类Bar的“括号内”是私有的。

其基本方面是内部类(与静态嵌套类相反)是其封闭类的一部分 它们不是分开的,也不是彼此分开的。 因此,就像封闭类的其他部分(构造函数和方法)可以访问其所有私有信息一样,内部类的所有成员也是如此。 从某种意义上说,内部类有点像我们用作方便抽象机制的虚构。 由于内部类是封闭类的一部分,它们的私有信息就是它的私有信息,因此与其他内部类共享。

根据JLS

类的主体声明成员(字段和方法以及嵌套类和接口)、实例和静态初始化器以及构造器。 成员的范围是该成员所属类的整个声明体。 字段、方法、成员类、成员接口和构造函数声明可以包括访问修饰符 public、protected 或 private。

因此,根据示例,类Bar和类Meh都属于类Foo

因此,根据规范的第一行,Foo 的任何成员都可以访问其所有其他成员,无论其是字段方法还是嵌套类/接口。


评论问题:

如果我将Bar中的变量设为public而不是私有,那么即使它来自内部类,它是否也可以在 Foo 之外访问?

是的,当然它可以从课堂外访问。 看下面的例子

class A {

    Foo foo = new Foo();
    Foo.Bar bar = foo.new Bar("name");

    public void someOtherMethod() {
        bar.barbar = "someOtherName"; 
        //this is valid only if barbar is public
        //or if it is default and within the same package
    }

}

内部类只是一种干净地分离真正属于原始外部类的一些功能的方法。 当您有 2 个要求时,可以使用它们:

如果外部类中的某些功能在单独的类中实现,它将是最清楚的。 即使它在一个单独的类中,其功能也与外部类的工作方式密切相关。 鉴于这些要求,内部类可以完全访问其外部类。 由于它们基本上是外部类的成员,因此它们可以访问外部类的方法和属性(包括私有)是有道理的。

我认为除非您与设计它的人交谈,否则您不会找到该语言设计背后的基本原理。 但是,人们通常可以通过 Java 语言规范深入了解“为什么”。 第 6.3 节(声明的范围)列出了范围规定的规则,并提供了这些规则的示例。

具体来说,您要询问的行为包含在以下声明中:

由块直接包围的局部类声明的范围是直接封闭块的其余部分,包括它自己的类声明。

您的两个本地类具有相同的范围,即“立即封闭的块”,特别是类Foo

也许在您的问题中,您可以解释为什么您认为封闭类应该无法访问barbar ,然后我们可以解决您对 Java 工作原理的任何误解。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM