Почему Java запрещает статические поля во внутренних классах?

class OuterClass {
 class InnerClass {
  static int i = 100; // compile error
  static void f() { } // compile error
 }
} 

Хотя не возможно получить доступ к статическому полю с OuterClass.InnerClass.i, если я хочу записать что-то, что должно быть статично, например, количество созданных объектов InnerClass, было бы полезно сделать то поле статичным. Итак, почему Java запрещает статические поля/методы во внутренних классах?

Править: Я знаю, как сделать компилятор довольным статическим вложенным классом (или статическим внутренним классом), но что я хочу знать, то, почему Java запрещает статические поля/методы во внутренних классах (или обычном внутреннем классе) от обоих аспекты разработки и реализации языка, если кто-то знает больше об этом.

79
задан Micha Wiedenmann 15 December 2017 в 10:19
поделиться

3 ответа

Идея внутренних классов заключается в том, чтобы действовать в контексте ограждающего экземпляра. Каким-то образом допуск статических переменных и методов противоречит этой мотивации?

8.1.2 Внутренние классы и окружающие их обстоятельства

Внутренний класс - это вложенный класс, который не объявлен явным или неявным образом статическим. Внутренние классы не могут объявлять статические инициализаторы (§8.7) или интерфейсы-членов. Внутренние классы не могут объявлять статические члены, если только они не являются компилируемыми полями с константами времени (§15.28).

27
ответ дан 24 November 2019 в 10:17
поделиться

я хочу знать, почему Java запрещает статические поля / методы внутри внутренних классов

Потому что эти внутренние классы являются внутренними классами "экземпляра". То есть они похожи на атрибут экземпляра включающего объекта.

Поскольку они являются «экземпляровыми» классами, нет никакого смысла разрешать статические функции, поскольку статические предназначены для работы в первую очередь без экземпляра.

Это как если бы вы пытались одновременно создать статический / экземплярный атрибут.

Возьмем следующий пример:

class Employee {
    public String name;
}

Если вы создадите два экземпляра сотрудника:

Employee a = new Employee(); 
a.name = "Oscar";

Employee b = new Employee();
b.name = "jcyang";

Понятно, почему каждый из них имеет собственное значение для свойства name , верно?

То же самое происходит с внутренним классом; каждый экземпляр внутреннего класса не зависит от другого экземпляра внутреннего класса.

Таким образом, если вы попытаетесь создать атрибут класса counter , не будет возможности разделить это значение между двумя разными экземплярами.

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

Когда вы создаете экземпляр a и b в приведенном выше примере, какое значение будет правильным для статической переменной count ? Определить его невозможно, поскольку существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

невозможно разделить эту ценность между двумя разными экземплярами.

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

Когда вы создаете экземпляр a и b в приведенном выше примере, какое значение будет правильным для статической переменной count ? Определить его невозможно, поскольку существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

невозможно разделить эту ценность между двумя разными экземплярами.

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

Когда вы создаете экземпляр a и b в приведенном выше примере, какое значение будет правильным для статической переменной count ? Определить его невозможно, поскольку существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

Когда вы создаете экземпляр a и b в приведенном выше примере, какое значение будет правильным для статической переменной count ? Определить его невозможно, поскольку существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

class Employee {
    public String name;
    class InnerData {
        static count; // ??? count of which ? a or b? 
     }
}

Когда вы создаете экземпляр a и b в приведенном выше примере, какое значение будет правильным для статической переменной count ? Определить его невозможно, поскольку существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

потому что существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

потому что существование класса InnerData полностью зависит от каждого из окружающих объектов.

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

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

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

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

45
ответ дан 24 November 2019 в 10:17
поделиться

InnerClass не может иметь статических членов, поскольку он принадлежит экземпляру (из OuterClass). Если вы объявите InnerClass статическим[1186664], чтобы отделить его от экземпляра, ваш код скомпилируется.

class OuterClass {
    static class InnerClass {
        static int i = 100; // no compile error
        static void f() { } // no compile error
    }
}

BTW: Вы все равно сможете создавать экземпляры InnerClass. static в этом контексте позволяет это произойти без экземпляра enclosureing экземпляра OuterClass.

.
33
ответ дан 24 November 2019 в 10:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: