【发布时间】:2011-12-18 20:18:41
【问题描述】:
Java 教程说静态嵌套类是通过使用封闭类的名称来访问的,例如 new EnclosureClassNameHere.StaticNestedClassNameHere()
我为什么要创建一个静态类的实例呢?谁能解释一下?
【问题讨论】:
Java 教程说静态嵌套类是通过使用封闭类的名称来访问的,例如 new EnclosureClassNameHere.StaticNestedClassNameHere()
我为什么要创建一个静态类的实例呢?谁能解释一下?
【问题讨论】:
"static" 在这种情况下可能会产生误导。它真正的意思是类可以独立存在。如果没有封闭类的实例,就不能存在非静态内部类。
IMO,当您开始在其所在类之外使用内部类时,您需要考虑将其移动并使其成为自己的顶级类。在极少数情况下,类之间的关系如此紧密耦合以至于您需要将其保留为内部类。
在您的代码示例中:
OuterClass.StaticNestedClass nestedObject = new OuterClass.StaticNestedClass();
您正在创建一个独立的 StaticNestedClass 实例。
如果它不是静态的,你就不能这样做。您只能从 OuterClass 的实例创建 StaticNestedClass() 的实例。
如果您将其移动到自己的 .java 文件中,您可以几乎相同地对待它:
StaticNestedClass notNestedAnymore = new StaticNestedClass();
至于你真正的问题:你为什么要创建它的一个实例?出于同样的原因,您创建任何类的实例 - 它会完成一些您需要的工作。
【讨论】:
这段代码没有什么令人困惑的地方。静态嵌套类只是引入另一个命名空间的一种方式。
通过创建静态嵌套类,您可以表达外部类和内部类之间非常紧密的关系。通常嵌套类是一个助手或外部类的一部分。例如,当您创建 Tree 类时,Node 类是嵌套静态类的理想选择。 Tree.Node 清楚地解释了 Node 类的用途。
其实static关键字用法和static字段是一致的。在这两种情况下,您都可以在没有封闭类实例的情况下访问 static 实体。对于static 类,它的基本意思是:“我可以创建这个静态嵌套类的实例,而无需外部类的实例”。默认情况下(不使用static 关键字时)嵌套类变为内部类。在这种情况下,你不能简单地写:
new OuterClass.StaticNestedClass();
相反,您需要使用有点晦涩的语法传递OuterClass instance:
OuterClass outerClassInstance = new OuterClass();
outerClassInstance.new InnerClass();
幸运的是,当new InnerClass() 在OuterClass 主体内部执行时,this 被隐式用作封闭实例。
【讨论】:
static 的性质。您正在考虑静态类变量——除了这里类本身是静态的,这与创建类的实例是正交的。
在java中,内部类有一个对外部类实例的隐式引用。这样您就可以直接访问外部类的成员,这在用于回调的匿名类中很有用。
class A{
private int a = 3;
class Inner{
Inner(){
System.out.println(a);//also A.this.a
}
}
static class StaticInner{
StaticInner(){
System.out.println(a);//FAILS
}
}
}
声明一个静态内部类只是删除这个隐式引用,这是静态和非静态内部类之间的唯一区别。
【讨论】: