代码之家  ›  专栏  ›  技术社区  ›  peter.murray.rust

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

  •  2
  • peter.murray.rust  · 技术社区  · 15 年前

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

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

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

    4 回复  |  直到 11 年前
        1
  •  5
  •   Vitaliy    15 年前

    jorn的说法是正确的,通常表现为以下经验法则:

    嵌套类应该被设为私有的,这意味着宿主类的保留辅助逻辑,而不是更多的。如果您不能使它们成为私有的,那么可能不应该嵌套它们。

    例外情况是,当您定义一个嵌套类以允许轻松访问托管类的状态时,在这种情况下,您应该 考虑 只需合并两个类来增加内聚力。

        2
  •  8
  •   Jorn    15 年前

    这取决于类的用途。例如,如果它与外部类耦合,就像map.entry一样,只需将其留在其中。但是,如果使用没有封闭类型的类是有意义的,那么您也可以将它提升到顶级类。

        3
  •  2
  •   scottb    11 年前

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

    但是,对于静态嵌套类,需要记住的一件重要事情是:从编译器和JVM的角度来看,静态嵌套类是顶级类。事实上,编译器在编译时将它们逻辑地实现为顶级类(至少它曾经实现过,我认为它仍然实现过)。

    那么,为什么要有人使用静态嵌套类呢?为什么不一直写顶级的课程呢?

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

    class DB {
    
        static class Client {
        ...
        }
    
        static class Encounter {
        ...
        }
    
        static class Service {
        ...
        }
    
    }
    

    要使用其中一个模型的实例:

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

    在我看来,这使得代码更具可读性,因为在代码中很明显,正在创建的对象是从我的一个数据库模型派生出来的。它还将模型的类定义保持在一个公共标题下,我认为这有助于使项目更容易理解。

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

        4
  •  0
  •   LiorH    15 年前

    我喜欢静态内部类,因为它们提供了封闭类的松耦合(不能访问封闭类的私有成员),静态内部类也很容易升级到顶级(因为松耦合属性)。

    有一个简单的经验法则是什么时候提升他们:
    如果另一个类(非封闭类)需要引用\请使用内部类。