考虑到我对编程的所有其他类型静态特性的了解,我认为答案是"否"。然而,看到像OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();这样的声明让我感到惊讶。
您可以一直尝试它,看看它是否编译:—)
为什么您认为static内部类是实例控制的?这是一个非常有趣的假设,也许值得研究。想写多少就写多少,写多少就写多少,也许会引出更有趣的讨论。
你为什么认为答案是否定的?仅仅因为您可以对单例模式使用"static"?
@多基因润滑剂,@searles:困惑的根源在我看来很明显。静态字段"只存在一次",这是初学者很早就学会的概念。静态方法也可以这样理解(错误)(这会导致诸如"很多方法会使对象变大吗?"之类的问题)。.难怪有人不清楚关键字在应用于嵌套类时的不同含义。
@迈克尔:很有道理。这是一个很好的问题,现在我明白了困惑的根源。
有趣。似乎是时候加深我对"静态"的理解了。下面是我的理解和假设的基础:静态循环变量、函数变量或类字段超越实例——它指的是内存中的相同数据,而不管类实例、函数实例(我使用的术语很轻)或循环块实例(同样,使用的"实例"很轻,不能想到更合适的术语)。静态类字段和成员函数独立于实例。在所有这些情况下,"静态"似乎引用了一些超越实例并且是奇异的东西。
因此,我假设静态嵌套类是奇异的。
@ Sturmin 98:注意,Java中没有静态循环变量或函数变量,只有字段、方法和嵌套类可以是静态的。
这类问题的最佳答案是"试一试看"
@Stormin986:考虑static的最好(也是正确的)方法是它属于类型,而不是类型的实例。
谢谢大家,这次讨论很有帮助。
是的,在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
public static class AbstractMap.SimpleEntry
可能是最著名的嵌套类型。显然是多次实例化的。
现在,当然嵌套类型可以执行自己的实例控制(例如private构造函数、singleton模式等),但这与它是嵌套类型这一事实无关。另外,如果嵌套类型是一个static enum,那么当然您根本无法实例化它。
但是,一般来说,可以多次实例化一个static嵌套类型。
注意,从技术上讲,static嵌套类型不是"内部"类型。JLS 8.1.3内部类和封闭实例
An inner class is a nested class that is not explicitly or implicitly declared static.
也就是说,根据jls的术语,内部类不是static。如果它是static,那么它只是一个嵌套类型。
那么,static是什么意思?
static只是表示嵌套类型不需要实例化封闭类型的实例。也见
Java内部类和静态嵌套类小精灵
JAVA:静态与非静态内部类
谢谢!当我第一次思考这个问题时,正如我在对我的问题的评论中所描述的那样,我的想法是"无论是静态的还是奇异的,尽管所附的上下文是实例"。现在,当我仔细考虑您对"static"的定义时,我重新定义了我对术语的理解,即"任何静态的东西都独立于封闭上下文的实例而存在"——因此,静态嵌套类除了其父类的实例之外还存在。我相信对它的理解将适用于循环变量、函数变量和类成员上下文中的静态。
我想得越多:把"单数"和"静态"的概念联系起来是一个微妙的错误。循环变量、函数变量和类字段对我来说是单数的唯一原因是它们是声明性语句,而不是类型定义语句。因此,静态类是唯一既静态又能用于定义新对象的东西(至少是马上想到的)。
@斯托曼986:也许再问一个问题,"static是什么意思?".
Polygene润滑剂,为了反复检查,我在嵌套类中添加了一个字段"state",所有内容都保持正常工作。干杯
@polygenelubricants :
But in general, yes, a static nested
type can be instantiated multiple
times.
为了确保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 inners = new ArrayList();
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
这是合法的。内部类是静态的这一事实在这里给了您一个好处;它的实例没有绑定到包含类的任何实例,因此它们可以自由地实例化(只要访问限定符允许)。
但是,代价是内部类不能使用包含类的非静态成员/方法。
静态嵌套类确实是实例——如前所述,它们是顶级类,位于"外部"类的名称空间中,并且遵循与"外部"类的引用相关的静态语义。此代码示例演示:
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
内部类可以使用包含类的非静态成员/方法。它只能通过封闭类的对象引用来使用它们-
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());
}
}
因此,内部类不必为无法访问封闭类的非静态成员而付出代价。
是的,你可以随心所欲地多次引用它。
也许你看到这一点的原因,是因为程序考虑在某个地方存储一个引用。尽管我同意你的观点,但这似乎很奇怪:S