前言
静态让我下意识觉得这是不可以的。实例化,是面向对象的术语,类被实例化为对象。静态内容,是全局的,不需要通过实例就可以使用。
我询问了几个人,他们想法都和我差不多,我们的理解都有些偏差。这有必要仔细看看了。
例子
public static void main(String[] args) {
StaticTest.StaticNestedClass staticNestedClass = new StaticTest.StaticNestedClass();
staticNestedClass.printI();
StaticTest s = new StaticTest();
StaticTest.NestedClass nestedClass = s.new NestedClass();
// StaticTest.StaticNestedClass staticNestedClass=s.new StaticNestedClass();// 无法通过编译
nestedClass.printI();
nestedClass.printJ();
}
public class StaticTest {
public static int i = 1;
private int j;
public static class StaticNestedClass {
public void printI() {
System.out.println(i);
}
public void printJ() {
// System.out.println(j); // 无法通过编译
}
}
public class NestedClass {
public void printI() {
System.out.println(i);
}
public void printJ() {
System.out.println(j);
}
}
}
NestedClass | StaticNestedClass | |
---|---|---|
可否被实例化 | 可以 | 可以 |
可否访问外部类静态属性 | 可以 | 可以 |
可否访问外部类非静态属性 | 可以 | 不可以 |
实例化 | 通过已经被实例化的外部类对象 | 直接通过外部类 |
总结
可能是把静态和抽象搞混了,抽象类是不能被实例化的,静态和能否被实例化没有实在的关系。
StaticNestedClass
中的 static,可能只是指不依赖外部类了,static 这个关键字和面向对象的关系并不是想象中那么强。
顺便,搜到的几个回答,看来迷惑的不只我一个人。
The significance of
static
with a class definition is not whether the class can be instantiated or not, but rather whether the class must be instantiated from within a non-static method of the outer class or not.Non-static inner class instances are tied to the instance that created them – there’s a pointer in the inner class instance back to the creating instance (which is useful in a number of ways). Static inner class instances are not tied to the creating instance.
(I worked in the innards of the JVM for about 10 years and I still find this confusing.)
Yes, there is nothing in the semantics of a
static
nested type that would stop you from doing that. This snippet runs fine.public class MultipleNested { static class Nested { } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Nested(); } } }
See also
public static interface Map.Entry<K,V>
public static class AbstractMap.SimpleEntry<K,V>
- Probably the most well-known nested type. Obviously instantiated multiple times.
Now, of course the nested type can do its own instance control (e.g.
private
constructors, singleton pattern, etc) but that has nothing to do with the fact that it’s a nested type. Also, if the nested type is astatic enum
, of course you can’t instantiate it at all.But in general, yes, a
static
nested type can be instantiated multiple times.Note that technically, a
static
nested type is not an “inner” type.JLS 8.1.3 Inner Classes and Enclosing Instances
An inner class is a nested class that is not explicitly or implicitly declared
static
.That is, according to JLS terminology, an inner class is one that isn’t
static
. If it’sstatic
, then it’s just a nested type.*So what does
static
mean?*
static
simply means that the nested type does not need an instance of the enclosing type to be instantiated.See also