доступ к внешнему классу из внутреннего вложенного перечисления - PullRequest
21 голосов
/ 10 декабря 2011

Есть ли выход на улицу?

public class OuterClass  {
    String data;

    public void outerMethod(String data) {
         this.data = data;
    }

    public enum InnerEnum {
        OPTION1("someData"),
        OPTION2("otherData");

        InnerEnum(String data) {
              // Does not work:             
              OuterClass.this.outerMethod(data);
        }
    }
}

Ответы [ 3 ]

17 голосов
/ 10 декабря 2011

Как сказал Эрик, перечисления неявно статичны.Чтобы сделать то, что вы хотите, добавьте метод callOuterMethod(OuterClass oc), который вызывает oc.outerMethod(data), чтобы сделать то, что вы хотите:

public enum InnerEnum {
    OPTION1("someData"),
    OPTION2("otherData");

    final String data;

    InnerEnum(String data) {
       this.data = data;             
    }

    void callOuterMethod(OuterClass oc) {
        oc.outerMethod(data);
    }
}
7 голосов
/ 10 декабря 2011

Не могу этого сделать. Перечисление неявно статично, даже если вы не объявили это. Смотрите похожий вопрос / ответ:

"Вложенные типы перечислений неявно статичны. Допустимо явно объявлять вложенные Тип enum должен быть статическим. "

Есть ли в Java типы enum внутри класса static?

4 голосов
/ 10 декабря 2011

Я полагаю, вы путаете экземпляры объектов с типами. То, что вы объявили, это два вложенных типа. Это не то же самое, что два экземпляра вложенных объектов.

Ключевое слово this не имеет значения при работе с типами. Это имеет значение только при работе с экземплярами объекта. Таким образом, если вы пытаетесь вызвать метод экземпляра внешнего типа из внутреннего типа, вам нужна ссылка на экземпляр внешнего типа.

Однако, если вы сделаете метод внешнего типа статическим, вы можете вызвать статический метод из вложенного типа, не обращаясь к экземпляру внешнего типа. Просто имейте в виду, что если вы сделаете это, метод будет «одинаковым для всех экземпляров» - то есть он будет использовать любое состояние со всеми экземплярами OuterClass - так что он сможет получить доступ только к статическим членам типа.

В приведенном ниже примере outerMethod объявлен статическим, и поэтому он может быть вызван из вложенного типа без необходимости ссылки на экземпляр OuterClass. Однако, делая это, он больше не может получить доступ к закрытому элементу экземпляра data (без ссылки на экземпляр, конечно). Вы можете объявить статический член staticData и получить к нему доступ, но имейте в виду, что этот член будет использоваться всеми экземплярами OuterClass и всеми вызовами externalMethod.

public class OuterClass  {

        String data;                 // instance member - can not be accessed from static methods
                                     //   without a reference to an instance of OuterClass

        static String staticData;    // shared by all instances of OuterClass, and subsequently
                                     //   by all invocations of outerMethod

        // By making this method static you can invoke it from the nested type 
        //  without needing a reference to an instance of OuterClass. However, you can
        //  no longer use `this` inside the method now because it's a static method of
        //  the type OuterClass
    public static void outerMethod(String data) {

            //this.data = data;  --- will not work anymore

            // could use a static field instead (shared by all instances)
            staticData = data;
    }

    public enum InnerEnum {
        OPTION1("someData"),
        OPTION2("otherData");

        InnerEnum(String data) {
                    // Calling the static method on the outer type
                    OuterClass.outerMethod(data);
        }
    }
}
...