loading...

Effective Java! Favor Static Members Classes over Non-Static

kylec32 profile image Kyle Carter ・3 min read

Effective Java Review (36 Part Series)

1) Effective Java Tuesday! Let's Consider Static Factory Methods 2) Effective Java Tuesday! The Builder Pattern! 3 ... 34 3) Effective Java Tuesday! Singletons! 4) Effective Java Tuesday! Utility Classes! 5) Effective Java Tuesday! Prefer Dependency Injection! 6) Effective Java Tuesday! Avoid Creating Unnecessary Objects! 7) Effective Java Tuesday! Don't Leak Object References! 8) Effective Java Tuesday! Avoid Finalizers and Cleaners! 9) Effective Java Tuesday! Prefer try-with-resources 10) Effective Java Tuesday! Obey the `equals` contract 11) Effective Java Tuesday! Obey the `hashCode` contract 12) Effective Java Tuesday! Override `toString` 13) Effective Java Tuesday! Override `clone` judiciously 14) Effective Java Tuesday! Consider Implementing `Comparable` 15) Effective Java Tuesday! Minimize the Accessibility of Classes and Member 16) Effective Java Tuesday! In Public Classes, Use Accessors, Not Public Fields 17) Effective Java Tuesday! Minimize Mutability 18) Effective Java Tuesday! Favor Composition Over Inheritance 19) Effective Java Tuesday! Design and Document Classes for Inheritance or Else Prohibit It. 20) Effective Java Tuesday! Prefer Interfaces to Abstract Classes 21) Effective Java! Design Interfaces for Posterity 22) Effective Java! Use Interfaces Only to Define Types 23) Effective Java! Prefer Class Hierarchies to Tagged Classes 24) Effective Java! Favor Static Members Classes over Non-Static 25) Effective Java! Limit Source Files to a Single Top-Level Class 26) Effective Java! Don't Use Raw Types 27) Effective Java! Elminate Unchecked Warnings 28) Effective Java! Prefer Lists to Array 29) Effective Java! Favor Generic Types 30) Effective Java! Favor Generic Methods 31) Effective Java! Use Bounded Wildcards to Increase API Flexibility 32) Effective Java! Combine Generics and Varargs Judiciously 33) Effective Java! Consider Typesafe Hetergenous Containers 34) Effective Java! Use Enums Instead of int Constants 35) Effective Java! Use Instance Fields Instead of Ordinals 36) Effective Java! Use EnumSet Instead of Bit Fields

Java provides four ways to declare a class within another class: static member class, nonstatic member classes, anonymous classes, and local classes. Each type has it's benefits and it's downsides so understanding the correct use cases for each type will help us use the right one in our code. Let's go over each type.

Static member class: This is the simplest of the nested class options. This ends up being basically a regular class that happens to be inside of a different class. It can be retrieved without already having a reference to the enclosing class. These classes are a static member of the enclosing class and obey the same visibility rules as other members of the class. A common use for this type of class is as a helper to the enclosing class. For example let's consider a Calculator class. Perhaps it would have an Operation nested class that includes a number of constants that define different operations that could be performed in the calculator. These would be accessed as follows Calculator.Operation.PLUS or Calculator.Operation.MINUS. This creates a nice organization for accessing these helper classes. Another place that you will see these static nested classes being used is with the Builder pattern where the builder object is a nested class inside of the class being built.

Nonstatic member class: The only difference between the declaration between a static nested class and a nonstatic nested class is the word static but this one word difference has quite a difference between the two types. Each instance of the enclosing class has an implicit connection to the enclosing class in this case and has access to the enclosing class's members. This method cannot be used if the nested class should be able to exist outside the context the enclosing class as this is impossible in a nonstatic nested class. The connection between the enclosing class and the nested class gets created on the enclosing class creation. This connection takes time to create and also takes up space. A use case for this type of nested class is when using the Adapter pattern where it allows the state of the class to be viewed as an unrelated type. This is a great use case as this method allows access to that internal state while still allowing the creation of a new class. We can see these uses in the wild with Map's keyset, entryset, and values as well as Set and List's iterator. So nonstatic nested member classes seem to have a lot of power, what are the downsides? As mentioned above, the connection of the enclosing and the nested class take time to create as well as memory on the heap. If you don't need the benefits of the the nonstatic type then there is no need to pay this price. It is even worse in that it becomes much easier to create memory leaks with a nonstatic nested class as the nested class can hold a reference to the enclosing class that can lead to a class that should be eligible for garbage collection from being collected.

Anonymous class: Anonymous classes come with a number of limitations. You can't instantiate them other than at the point of declaration, you can't perform instanceof inquiries of the class, or do anything else that requires a class name. Anonymous classes also can't implement multiple interfaces nor extend a class and implement an interface at the same time. Before lambda's came around in Java 8 anonymous classes were the preferred way of creating small objects on the fly, now lambda's are the preferred method.

Local class: This is the least used method and one I personally have never used. These can be declared basically anywhere where a local variable can be declared. Local classes can have names, can be used repeatedly, and can reference the enclosing class's members. These should be kept short in order to avoid harming readability.

So as we can see each type has it's own reason for existing and have their place in the world. A main take away from this post is the difference between the static and nonstatic member nested class. When in doubt start off with a static class as they are safer and only once you absolutely need the functionality of the nonstatic nested class should you use them.

Effective Java Review (36 Part Series)

1) Effective Java Tuesday! Let's Consider Static Factory Methods 2) Effective Java Tuesday! The Builder Pattern! 3 ... 34 3) Effective Java Tuesday! Singletons! 4) Effective Java Tuesday! Utility Classes! 5) Effective Java Tuesday! Prefer Dependency Injection! 6) Effective Java Tuesday! Avoid Creating Unnecessary Objects! 7) Effective Java Tuesday! Don't Leak Object References! 8) Effective Java Tuesday! Avoid Finalizers and Cleaners! 9) Effective Java Tuesday! Prefer try-with-resources 10) Effective Java Tuesday! Obey the `equals` contract 11) Effective Java Tuesday! Obey the `hashCode` contract 12) Effective Java Tuesday! Override `toString` 13) Effective Java Tuesday! Override `clone` judiciously 14) Effective Java Tuesday! Consider Implementing `Comparable` 15) Effective Java Tuesday! Minimize the Accessibility of Classes and Member 16) Effective Java Tuesday! In Public Classes, Use Accessors, Not Public Fields 17) Effective Java Tuesday! Minimize Mutability 18) Effective Java Tuesday! Favor Composition Over Inheritance 19) Effective Java Tuesday! Design and Document Classes for Inheritance or Else Prohibit It. 20) Effective Java Tuesday! Prefer Interfaces to Abstract Classes 21) Effective Java! Design Interfaces for Posterity 22) Effective Java! Use Interfaces Only to Define Types 23) Effective Java! Prefer Class Hierarchies to Tagged Classes 24) Effective Java! Favor Static Members Classes over Non-Static 25) Effective Java! Limit Source Files to a Single Top-Level Class 26) Effective Java! Don't Use Raw Types 27) Effective Java! Elminate Unchecked Warnings 28) Effective Java! Prefer Lists to Array 29) Effective Java! Favor Generic Types 30) Effective Java! Favor Generic Methods 31) Effective Java! Use Bounded Wildcards to Increase API Flexibility 32) Effective Java! Combine Generics and Varargs Judiciously 33) Effective Java! Consider Typesafe Hetergenous Containers 34) Effective Java! Use Enums Instead of int Constants 35) Effective Java! Use Instance Fields Instead of Ordinals 36) Effective Java! Use EnumSet Instead of Bit Fields

Posted on by:

kylec32 profile

Kyle Carter

@kylec32

Backend Architect at MasterControl

Discussion

markdown guide
 

I think another feature of static class is that private members are visible to the outer class. This allows for some convenient uses of a static inner classes. In the case of Builders there is no need to provide getters for the members of the Builder. The constructor of the outer class can access the private member varaibles directly.