我继承了包含静态嵌套类的代码:
public class Foo {
// Foo fields and functions
// ...
private static class SGroup {
private static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();
public SGroup(int id, String type) {
// ...
}
}
}
从阅读SO(例如Java inner class and static nested class)我相信这相当于两个单独文件中的两个单独的类:
public class Foo {
// Foo fields and functions
// ...
}
和
public class SGroup {
static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();
public SGroup(int id, String type) {
// ...
}
}
如果这是正确的,那么维护静态嵌套类结构还是应该重构?
答案 0 :(得分:8)
这取决于课程的用途。如果它耦合到外部类,例如,就像Map.Entry一样,只需将其保留。但是,如果使用没有其封闭类型的类是有意义的,您也可以将它提升为顶级类。 / p>
答案 1 :(得分:5)
Jorn声明是正确的,它通常表现为以下经验法则:
嵌套类应该是私有的,意味着托管类的保持辅助逻辑,仅此而已。如果你不能将它们私有化,那么它们可能不应该嵌套。
例外情况是,当您定义嵌套类以允许轻松访问托管类的状态时,在这种情况下,您应该考虑简单地合并两个类以增加内聚。
答案 2 :(得分:2)
说“静态嵌套类”根本不是嵌套类并不是不恰当的。在内部类的上下文中讨论静态嵌套类是很方便的,因为它们在代码中声明的方式是相似的,并且因为静态嵌套类仍然必须以封闭类作为上下文命名。
但是,关于静态嵌套类需要牢记这一点:从编译器和JVM的角度来看,静态嵌套类是顶级类。事实上,编译器在编译时在逻辑上将它们作为顶级类实现(至少它曾经用过;我认为它仍然存在)。
那么,为什么有人会使用静态嵌套类?为什么不一直只写顶级课程?
对我来说,静态嵌套类提供了一种方便的机制,用于以保持项目层次结构良好和整洁的方式对密切相关的类进行逻辑分组。例如,假设我有一个包含以下表的数据库:客户端,遭遇者和服务。我可以使用单独的顶级类对这些表进行建模,它可以正常工作,但由于这些表都在同一个数据库中,并且与相同的数据相关,因此我发现将这些表建模为方便:
class DB {
static class Client {
...
}
static class Encounter {
...
}
static class Service {
...
}
}
使用其中一个模型的实例:
DB.Encounter enc = new DB.Encounter();
在我看来,这使得代码更具可读性,因为在代码中立即清楚地知道正在创建的对象是从我的一个数据库模型派生的。它还保留了在一个共同标题下链接的模型的类定义,我认为这有助于使项目更易于理解。
但是从JVM(以及编译器,它实现它们作为顶级类)的角度来看[正如它在编译时也提供“匿名”内部类名]),这些对象从顶层实例化类。使它们不依赖于任何对象的任何实例,也不能从静态嵌套类实例化的对象访问封闭类的任何私有成员。
答案 3 :(得分:0)
我喜欢静态内部类,因为它们提供了来自封闭类的松散耦合(无法访问封闭类的私有成员)静态内部类也很容易提升到顶层(因为松散耦合属性)。
有一个简单的拇指规则来推广它们:
如果另一个类(封闭的除外)需要引用\使用内部类。