这是对static
关键字的常见误解。
当您使用static
变量时,这意味着对于此类的所有对象或类似的对象,只有其中一个。
static Object thereWillBeOnlyOne = new Object();
但是,在内部类的上下文中,它意味着完全不同的东西。内部类static
与封闭类的对象没有联系,而非静态内部类则有。
一个static
内部类:
public class TrieMap<K extends CharSequence, V> extends AbstractMap<K, V> implements Map<K, V> {
private static class Entry<K extends CharSequence, V> implements Map.Entry<K, V> {
我的Map.Entry
类使用的TrieMap
类不需要引用创建它的对象,因此可以static
保存不必要的引用。
非static
内部类:
public final class StringWalker implements Iterable<Character> {
// The iteree
private final String s;
// Where to get the first character from.
private final int start;
// What to add to i (usually +/- 1).
private final int step;
// What should i be when we stop.
private final int stop;
// The Character iterator.
private final class CharacterIterator implements Iterator<Character> {
// Where I am.
private int i;
// The next character.
private Character next = null;
CharacterIterator() {
// Start at the start.
i = start;
}
public boolean hasNext() {
if (next == null) {
if (step > 0 ? i < stop : i > stop) {
next = s.charAt(i);
i += step;
}
}
return next != null;
}
对象内部CharacterIterator
是StringWalker
指要迭代的字符串,s
它在对象中只存在一次StringWalker
。因此,我可以创建许多 a 的迭代器,StringWalker
它们都走同一个字符串。
为什么会出现这种奇怪现象?
这种看似不合逻辑的二元性源于static
关键字 in的使用C
。
在C
你可以(或至少曾经能够)做:
void doSomething () {
static int x = 1;
if ( x < 3 ) {
} else {
}
x += 1;
}
每次调用该函数时,x
都将与上次离开时一样-在这种情况下递增。
这个概念是static
关键字表明该变量被其封闭块在范围内封闭,但在语义上被其父块封闭。即上面的代码大致相当于:
int x = 1;
void doSomething () {
if ( x < 3 ) {
} else {
}
x += 1;
}
但x
只允许在函数内部被引用。
把这个概念向前推进Java
,现在事情变得更有意义了。内部类的行为与在类外部声明的static
完全一样,而非static
内部类与其封闭的实例更紧密地结合在一起——实际上它可以直接引用该实例。
还:
class Thing {
static Object thereWillBeOnlyOne = new Object();
行为很像
Object thereWillBeOnlyOne = new Object();
class Thing {
如果它是合法的。
本课到此结束。