Может ли статический вложенный класс быть установлен несколько раз? - PullRequest
19 голосов
/ 27 апреля 2010

Учитывая то, что я знаю о любых других типах статических функций программирования - я бы подумал, что ответ «нет». Однако, когда я вижу такие утверждения, как OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();, я удивляюсь.

Ответы [ 6 ]

28 голосов
/ 27 апреля 2010

Да, в семантике вложенного типа static нет ничего, что помешало бы вам сделать это. Этот фрагмент отлично работает.

public class MultipleNested {
    static class Nested {
    }
    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            new Nested();
        }
    }
}

Смотри также


Теперь, конечно, вложенный тип может выполнять собственный контроль экземпляра (например, private конструкторы, шаблон синглтона и т. Д.), Но это не имеет ничего общего с тем фактом, что это вложенный тип. Кроме того, если вложенный тип является static enum, конечно, вы не можете создать его экземпляр вообще.

Но, как правило, да, вложенный тип static может создаваться несколько раз.

Обратите внимание, что технически вложенный тип static не является "внутренним" типом.

JLS 8.1.3 Внутренние классы и вложенные экземпляры

внутренний класс - это вложенный класс, который не объявлен явно или неявно static.

То есть, согласно терминологии JLS, внутренний класс - это класс, который не static. Если это static, то это просто вложенный тип.


Так что же означает static? 1057 *

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

Смотри также

6 голосов
/ 19 апреля 2011

@ полигенасмазочные материалы: А вообще да, статик вложенный тип может быть создан несколько раз.

Просто чтобы быть уверенным, что на 100% я расширил твой фрагмент:

public class MultipleInner {
    static class Inner {
        private int state;
        public int getState() { return state; }
        public void setState(int state) { this.state = state; }
    }

    public static void main(String[] args) {
        List<Inner> inners = new ArrayList<Inner>();
        for (int i = 0; i < 100; i++) {
            Inner inner = new Inner();
            inner.setState(i);
            inners.add(inner);
        }
        for (Inner inner : inners) {
            System.out.println(inner.getState());
        }
    }
}

И, конечно, результат:

0
1
2
3
.
.
.
97
98
99
3 голосов
/ 27 апреля 2010

Это законно. Тот факт, что внутренний класс является статическим, дает вам здесь преимущество; его экземпляры не привязаны ни к какому экземпляру содержащего класса, поэтому их можно свободно создавать (если это допускает квалификатор доступа).

Однако цена заключается в том, что внутренний класс не может использовать нестатические члены / методы содержащего класса.

0 голосов
/ 20 апреля 2019

Статические вложенные классы действительно являются экземплярами - это, как уже говорилось, классы верхнего уровня, которые живут в пространстве имен внешнего класса и подчиняются статической семантике в отношении ссылок на внешний класс. Этот пример кода демонстрирует:

public class OuterClass {
    String outerStr = "this is the outer class!!" ;
    public static class StaticNestedClass {
        String innerStr = "default / first instance" ;      
    }

    public static void main(String[] args) {
        OuterClass.StaticNestedClass nestedObject1 = new OuterClass.StaticNestedClass();        
        OuterClass.StaticNestedClass nestedObject2 = new OuterClass.StaticNestedClass();
        nestedObject2.innerStr = "second instance" ;
        System.out.println(nestedObject1.innerStr) ;
        System.out.println(nestedObject2.innerStr) ;
    }
}

output:

default / first instance 
second instance
0 голосов
/ 29 мая 2013

Внутренний класс может использовать нестатические члены / методы, содержащие класс. Он может использовать их только через ссылку на объект окружающего класса-

     public class MultipleInner {
      private int outerstate =10;
      static class Inner {
        private int state;
        public int getState() { return state; }
        public void setState(int state) { this.state = state; }
      }

     public static void main(String[] args) {       
        Inner inner = new Inner();
        inner.setState(new MultipleInner().outerstate);
        System.out.println(inner.getState());        
     }

}

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

0 голосов
/ 27 апреля 2010

Да, вы можете делать это столько раз, сколько захотите.

Возможно, причина, по которой вы это видите, в том, что программа думала о хранении ссылки где-нибудь. Хотя я согласен с тобой, кажется странным: S

...