首页 > 解决方案 > 嵌套类中阴影的所有可能性

问题描述

我在这个页面上遇到了下面的概念片段,它解释了相同的命名变量是如何在内部类实例的非静态/实例方法中隐藏的:

public class ShadowTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);  //23
            System.out.println("this.x = " + this.x);  //1
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); //0
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}

我想强调这里有三个方面:

  1. FirstLevel我们已经创建了内部类的实例
  2. methodInFirstLevel是非静态的
  3. 我们正在访问
    • x局部变量methodInFirstLevel
    • FirstLevel实例变量this.x
    • ShadowTest实例变量ShadowTest.this.x

我很快意识到可能有很多可能性。例如:

  1. 在上面的第 1 点中,我可以添加:
    • 我们可能决定不创建实例,即在类名上调用方法
    • 我们可以处理静态嵌套类,而不是内部类(在上面的同一链接中定义为非静态嵌套类) 。
  2. 在上面的第 2 点,我可以添加,调用静态方法
  3. 在第三点,我可以补充:
    • FirstLevel静态变量
    • ShadowTest静态变量

如果你检查组合变得相当大。我试图弄清楚在所有这些情况下如何进行访问。在下图中,我尝试将其以某种结构化的形式呈现。我已经用红色字体删除了不可能的组合。此外,为了更清楚起见,我还使用了类名InnerClass, (如上面链接中所用的其他示例)。只是占位符,让我思考我在下面上来时正在处理什么类型的课程。我已经把项目符号放在评论和答案中供您参考。我不确定这里的一切,尤其是粉红色的东西。OuterClassStaticNestedClass(#)

这让我非常困惑,尽管我已经付出了所有这些努力。我要找人确认。虽然我可以编写代码并检查每个案例,但我现在已经筋疲力尽了。

在此处输入图像描述

PS:我可能会 200+% 愚蠢地提出所有这些不必要的想法。我本可以记住上面代码中的内容并冷静下来。如果是这种情况,请也告诉。

标签: javainner-classes

解决方案


您记录想法的观点是合法的,我建议创建一个表格(或多个表格)以获得更好的概览。

它可能看起来像这样:

非静态内部类型

                      |   Outer class   |   Inner class  
----------------------+-----------------+----------------
   non-static member  |  Outer.this.x   |  [this.]x
----------------------+-----------------+----------------
       static member  |  Outer.x        |  [Inner.]x

请注意,语法不依赖于封闭方法,除非您不能从静态方法引用非静态变量。

在示例的第 20 + 21 行中,您可以通过访问任意对象的字段来解决此问题,这些对象的类型分别为InnerClass和。OuterClass因此,this关键字(和任何限定语法)被变量名替换。简而言之,这些行是正确的,但与主题无关。


推荐阅读