我应该将Java中的静态嵌套类重构为单独的类吗?

我应该将Java中的静态嵌套类重构为单独的类吗?,java,class,static,nested,Java,Class,Static,Nested,我继承了包含静态嵌套类的代码,如下所示: 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)

我继承了包含静态嵌套类的代码,如下所示:

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) {
// ...
        }
    }
}

公共类SGroup{
静态映射idMap=newhashmap();
公共SGroup(int-id,字符串类型){
// ...
}
}

如果这是正确的,那么维护静态嵌套类结构有什么好处,或者我应该重构吗?

这取决于类的用途。例如,如果它与外部类耦合,就像Map.Entry一样,只需将其保留在其中。但是,如果在不使用封闭类型的情况下使用该类是有意义的,您还可以将其升级为顶级类。

Jorn语句是正确的,它通常表现为以下经验法则:

嵌套类应该是私有的,这意味着宿主类的hold辅助逻辑仅此而已。如果不能将它们设为私有,则可能不应嵌套它们


例外情况是,当您定义嵌套类以便于访问宿主类的状态时,在这种情况下,您应该考虑简单地合并这两个类来增加内聚性。

< P>我喜欢静态内部类,因为它们提供了来自封闭类的松散耦合(没有对封闭类的私有成员的访问)。静态内部类也很容易升级到顶层(因为松散耦合属性)

提升他们时有一个简单的经验法则:

如果另一个类(非封闭类)需要引用\请使用内部类。

可以说“静态嵌套类”根本不是嵌套类。在内部类的上下文中讨论静态嵌套类是很方便的,因为它们在代码中的声明方式类似,而且静态嵌套类仍然必须以封闭类作为上下文命名

但是,关于静态嵌套类,需要记住一件重要的事情:从编译器和JVM的角度来看,静态嵌套类是顶级类。事实上,编译器在编译时以顶级类的形式在逻辑上实现它们(至少以前是这样;我认为现在仍然是这样)

那么,为什么任何人都应该使用静态嵌套类呢?为什么不一直写顶级课程呢

对我来说,静态嵌套类提供了一种方便的机制,用于以保持项目层次结构整洁的方式对密切相关的类进行逻辑分组。例如,假设我有一个包含以下表的数据库:客户机、遭遇和服务。我可以用单独的顶级类对这些表进行建模,这样可以很好地工作,但是由于这些表都在同一个数据库中,并且与相同的数据相关,因此我发现将这些表建模为:

class DB {

    static class Client {
    ...
    }

    static class Encounter {
    ...
    }

    static class Service {
    ...
    }

}
要使用其中一个模型的实例,请执行以下操作:

DB.Encounter enc = new DB.Encounter();
在我看来,这使代码更具可读性,因为在代码中很明显,正在创建的对象来自我的一个数据库模型。它还将模型的类定义链接在一个公共标题下,我认为这也有助于使项目更易于理解


但是从JVM(以及编译器的角度来看,编译器无论如何都将它们实现为顶级类[就像它在编译时也给出“匿名”内部类名称一样]),这些对象是从顶级类实例化的。生成它们不依赖于任何对象的任何实例,从静态嵌套类实例化的对象也不能访问封闭类的任何私有成员。

静态内部类可能访问其封闭类的私有成员,因此不能确保失去耦合。(当然,他们需要一个封闭类的实例来访问非静态类)。那么您要将java.util.Map.Entry分解成一个顶级类?我不同意你的看法。Map.条目如何符合我建议的规则?它既不是静态的,也不是类。尽管我同意将封闭类的引用传递给内部类会绕过松散耦合的整个概念。
Map.Entry
作为接口是隐式静态的。
class DB {

    static class Client {
    ...
    }

    static class Encounter {
    ...
    }

    static class Service {
    ...
    }

}
DB.Encounter enc = new DB.Encounter();