Можно ли запускать статический вложенный класс несколько раз?

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

Ответы

Ответ 1

Да, в семантике 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?

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

Смотрите также

Ответ 2

@polygenelubricants: Но, в общем, да, статическое вложенное тип может быть несколько экземпляров раз.

Просто чтобы убедиться, что 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

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

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

Ответ 4

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

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

Ответ 5

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

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

}

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

Ответ 6

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

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