Можно ли запускать статический вложенный класс несколько раз?
Учитывая то, что я знаю о любом другом типе статической функции программирования, я думаю, что ответ "нет". Однако, видение таких выражений, как 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
вложенный тип не является "внутренним" типом.
Внутренний класс - это вложенный класс, который не объявлен явно или неявно как 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