Доступ к полю внешнего класса - PullRequest
8 голосов
/ 30 июня 2011

Как получить доступ к полю внешнего класса, учитывая ссылку на объект внутреннего класса?

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 и многие другие варианты.Есть ли синтаксис, который делает то, что я хочу?

Ответы [ 3 ]

10 голосов
/ 13 августа 2012

Как насчет этого решения:

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; 
        }
    }
}
8 голосов
/ 30 июня 2011

Из-за пределов внутреннего класса, я считаю, что при наличии ссылки на экземпляр внутреннего класса невозможно ссылаться на члены экземпляра внешнего класса. Внутри нестатического внутреннего класса вы, конечно, можете ссылаться на них, используя синтаксис Outer.this.*.

Думайте об этом так: внутренний класс на самом деле является совершенно отдельным классом. У него есть сгенерированное компилятором поле (обычно называемое чем-то странным, например this$0). Внутри внутреннего класса язык позволяет ссылаться на это поле, используя Outer.this; однако этот синтаксический сахар недоступен вне самого внутреннего класса. Также не генерируемое компилятором поле.

2 голосов
/ 30 июня 2011

Есть два способа взглянуть на то, что вы делаете, статический метод или нестатический метод.

На первый взгляд, ваш пример больше похож на статический метод, так как онманипулирование состоянием параметра, а не его собственным состоянием.Статическая проблема была рассмотрена ранее, например, см. В Java, как я могу получить доступ к внешнему классу, когда я не во внутреннем классе?

Но ваш пример нестатический метод, и я думаю, что вижу, что вы получаете, и почему вы думаете, что внешняя ссылка должна быть возможной.В конце концов, существуют другие ситуации, в которых вы можете получить доступ к деталям реализации других экземпляров вашего собственного типа - например, при переопределении equals часто ссылаются на поля закрытого члена входного параметра.К сожалению, я просто не думаю, что java предоставляет способ ссылаться на чужой лексически заключенный экземпляр.Вероятно, это как-то связано с способом, которым java фактически реализует нестатические внутренние классы .Java использует this$0 для своих собственных целей, но у вас нет доступа к этому синтетическому полю.

...