鉴于我对编程的所有其他类型的静态特性的了解——我认为答案是否定的。然而,看到这样的陈述OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
让我感到奇怪。
6 回答
是的,嵌套类型的语义中没有任何东西static
可以阻止您这样做。这个片段运行良好。
public class MultipleNested {
static class Nested {
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
new Nested();
}
}
}
也可以看看
public static interface Map.Entry<K,V>
public static class AbstractMap.SimpleEntry<K,V>
- 可能是最著名的嵌套类型。显然多次实例化。
现在,嵌套类型当然可以进行自己的实例控制(例如private
构造函数、单例模式等),但这与它是嵌套类型这一事实无关。另外,如果嵌套类型是 a static enum
,当然你根本不能实例化它。
但总的来说,是的,一个static
嵌套类型可以被实例化多次。
请注意,从技术上讲,static
嵌套类型不是“内部”类型。
JLS 8.1.3 内部类和封闭实例
内部类是没有显式或隐式声明的嵌套类
static
。
也就是说,根据 JLS 术语,内部类不是static
. 如果是static
,那么它只是一个嵌套类型。
那么是什么static
意思呢?
static
仅仅意味着嵌套类型不需要实例化封闭类型的实例。
也可以看看
@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
这是合法的。内部类是静态的这一事实给您带来了好处;它的实例不绑定到包含类的任何实例,因此可以自由地实例化它们(只要访问限定符允许)。
然而,代价是内部类不能使用包含类的非静态成员/方法。
是的,您可以根据需要多次创建它的实例。
也许你看到这个的原因是因为程序考虑在某个地方存储一个引用。虽然我同意你的观点似乎很奇怪:S
内部类可以使用包含类的非静态成员/方法。它只能通过封闭类的对象引用来使用它们-
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());
}
}
因此,内部类不必为无法访问封闭类的非静态成员而付出代价。
静态嵌套类确实是实例化的——如前所述,它们是位于“外部”类的命名空间中的顶级类,并遵守关于“外部”类引用的静态语义。此代码示例演示:
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