Java 外部类的访问字段

Java 外部类的访问字段,java,field,inner-classes,Java,Field,Inner Classes,给定对内部类对象的引用,如何访问外部类的字段 class Outer { int field; class Inner { void method(Inner parameter) { // working on the current instance is easy :) field = 0; Outer.this.field = 1;

给定对内部类对象的引用,如何访问外部类的字段

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
和许多其他变体。是否有一种语法可以满足我的需要?

从内部类之外,我相信,如果引用内部类实例,就无法引用外部类实例的成员。当然,在非静态内部类中,您可以使用
Outer.this.*
语法引用它们


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

有两种方法可以查看您正在执行的操作,一种是静态方法,另一种是非静态方法

乍一看,您的示例更像是一个静态方法,因为它是在操纵参数的状态,而不是自己的状态。静态问题之前已经讨论过,例如,请参阅


但是你的例子是一个非静态的方法,我想我知道你得到了什么,以及为什么你认为外部引用是可能的。毕竟,在其他情况下,您可以访问自己类型的其他实例的实现细节——例如,在重写equals时引用输入参数的私有成员字段是很常见的。不幸的是,我不认为java提供了一种引用另一个词汇封闭实例的方法。这可能与此有关。Java使用
这个$0
是为了它自己的目的,但您无权访问这个合成字段。

这个解决方案怎么样:

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; 
        }
    }
}

一个内部类的目的不是仅仅在它的外部类中使用吗?我认为这就是实现它的方法。如果你觉得这是错误的,也许你可以以不同的方式思考重构或构建这些类?我不知道还有其他方法可以做到这一点,但我要说的是,如果你不得不这样做,通常意味着你应该重新考虑设计。@Overbose-很多内部类实例都传递给了世界。例如,许多迭代器类是其Iterable集合的内部类。内部类有助于减少名称空间的混乱(例如,
Float
Arc2D.Float
CubicCurve2D.Float
DataBuffer.Float
,等等)。这就是我通常的做法,尽管我会为您的示例选择一个非原语字段。仅存储对父作用域的引用并通过它访问字段可以避免在
字段
是对象而不是原语时使用过时的引用,这是这种方法的主要优点。