【问题标题】:Accessing field of outer class访问外部类的字段
【发布时间】:2011-09-26 02:18:46
【问题描述】:

在给定对内部类对象的引用的情况下,如何访问外部类的字段?

class Outer
{
    int field;

    class Inner
    {
        void method(Inner parameter)
        {
            // working on the current instance is easy :)
            field = 0;
            Outer.this.field = 1;

            // working on another instance is hard :(
            parameter.field = 2;              // does not compile
            parameter.Outer.this.field = 3;   // does not compile
            parameter.outer().field = 4;      // This works...
        }

        // ...but I really don't want to have to write this method!
        Outer outer()
        {
            return Outer.this;
        }
    }
}

我还尝试了Outer.parameter.field 和许多其他变体。有没有我想要的语法?

【问题讨论】:

  • 内部类的目的不是只在其外部类中使用吗?
  • 我认为这就是这样做的方法。如果您觉得不对,也许您可​​以考虑重构或以不同的方式构建这些类?
  • 我不知道有什么其他方法可以做到这一点,但我会说,如果你不得不做这样的扭曲,这通常意味着你应该重新考虑设计。
  • @Overbose - 许多内部类实例被传递给世界。例如,许多 Iterator 类是其 Iterable 集合的内部类。内部类有助于减少命名空间混乱(例如,FloatArc2D.FloatCubicCurve2D.FloatDataBuffer.Float 等)

标签: java field inner-classes


【解决方案1】:

这个解决方案怎么样:

class Outer
{
    int field;

    class Inner
    {
        final Outer outer = Outer.this;
        void method(Inner parameter)
        {
            // working on the current instance is easy :)
            field = 0;
            Outer.this.field = 1;

            // working on another instance:
            parameter.outer.field = 2; 
        }
    }
}

【讨论】:

  • 这就是我一直这样做的方式,尽管我会为您的示例选择一个非原始字段。仅存储对父作用域的引用并通过它访问字段可以避免在 field 是 Object 而不是原语时使用陈旧的引用,这是这种方法的主要好处。
【解决方案2】:

从内部类的外部,我相信在给定对内部类实例的引用的情况下,没有办法引用外部类实例的成员。在非静态内部类中,您当然可以使用 Outer.this.* 语法引用它们。

这样想:内部类实际上是一个完全独立的类。它有一个编译器生成的字段(通常命名为 this$0 之类的奇怪名称)。在内部类中,该语言允许您使用 Outer.this 引用该字段;但是,这种语法糖在内部类本身之外是不可用的。编译器生成的字段也不是。

【讨论】:

    【解决方案3】:

    有两种方法可以查看您正在执行的操作,作为静态方法或作为非静态方法。

    乍一看,您的示例看起来更像是一个静态方法,因为它正在操作参数的状态而不是其自身的状态。静态问题之前已经介绍过,例如见In Java, how do I access the outer class when I'm not in the inner class?

    但是你的例子是一个非静态方法,我想我明白你得到了什么以及为什么你认为外部引用应该是可能的。毕竟,在其他情况下,您可以访问您自己类型的其他实例的实现细节——例如,在覆盖 equals 时引用输入参数的私有成员字段是很常见的。不幸的是,我只是不认为 java 提供了一种引用另一个词法封闭实例的方法。这可能与the way that java actually implements non-static inner classes 有关。 Java 将this$0 用于其自身目的,但您无权访问此合成字段。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-13
      • 1970-01-01
      • 2021-04-21
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多