简体   繁体   中英

Should I refactor static nested classes in Java into separate classes?

I have inherited code which contains static nested classes as:

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

From reading SO (eg Java inner class and static nested class ) I believe that this is equivalent to two separate classes in two separate files:

 public class Foo {

    // Foo fields and functions
    // ...
}

and

public class SGroup {
    static Map<Integer, SGroup> idMap = new HashMap<Integer, SGroup>();

    public SGroup(int id, String type) {
// ...
    }
}

If this is correct is there any advantage to maintaining the static nested class structure or should I refactor?

It depends on what the class is used for. If it's coupled to the outer class, for example, just like Map.Entry, just leave it in. However, if it makes sense to use the class without its enclosing type, you may as well promote it to a top level class.

Jorn statement is correct and it's usually manifests itself as the following rule of thumb:

Nested classes should be made private, Meaning that the hold auxiliary logic for the hosting class and nothing more. If you cant make them private- thet probably should not be nested.

The exception is when you define a nested class to allow easy access to the state of the hosting class, in that case you should consider simply merging both classes to increase cohesion.

It is not improper to say that "static nested classes" are not nested classes at all. It is convenient to discuss static nested classes in the context of inner classes because the way they are declared in code is similar and also because a static nested class still has to be named with the enclosing class as a context.

However, here is an important thing to keep in mind about static nested classes: from the point of view of the compiler and the JVM, static nested classes are top level classes. In fact, the compiler implements them logically at compile time as top level classes (at least it used to; I think it still does).

Why, then, should anyone ever use static nested classes? Why not just write top level classes all the time?

For me, static nested classes provide a convenient mechanism for logically grouping closely related classes in a manner that keeps my project hierarchy nice and tidy. For example, say that I have a database with the following tables: Clients, Encounters, and Services. I -could- model these tables with separate top-level classes and it would work fine, but since these tables are all in the same database and relate to the same data, I find it convenient to model these as:

class DB {

    static class Client {
    ...
    }

    static class Encounter {
    ...
    }

    static class Service {
    ...
    }

}

To use an instance of one of the models:

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

In my view, this makes code more readable since it is immediately clear in the code that the object that is being created derives from one of my database models. It also keeps the class definitions for the models linked under a common heading which I also think helps make projects simpler to understand.

But from the point of view of the JVM (and the compiler, which implements them as top level classes anyway [just as it also gives "anonymous" inner classes names at compile time]), these objects are instantiated from top level classes. Making them does not depend on any instance of any object, nor can objects instantiated from a static nested class access any private members of the enclosing class.

I like static inner classes as they provide loose coupling from the enclosing class (no access to private members of the enclosing class) static inner classes are also easy to promote to top level (because of the loose coupling attribute).

There is a simple rule of the thumb when to promote them:
If another class (other than the enclosing) needs to reference \\ use the inner class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM