Creating & Destroying Objects
The document discusses best practices for object creation and destruction in Java. It covers 6 items: 1) using static factory methods instead of constructors, 2) using builders for classes with many constructor parameters, 3) enforcing singleton properties with private constructors or enums, 4) enforcing non-instantiability with private constructors, 5) avoiding unnecessary object creation, and 6) eliminating obsolete references to avoid memory leaks. The document provides examples and explanations for each best practice.
6. Item 1 Premise
● Create an object
● Implicitly not create objects when unnecessary
● Ability to create a object of subtype
7. Item1 - Solution
● Provide static factory methods
● Advantages
– Unlike constructors they have names
– Not required each time you create a new object
● E.g: Boolean.valueof(boolean) – never creates a object
– Can return a object of any subtype of return type
● Disadvantages
– Classes without public or protected members cannot be sub classed
● This has a hidden advantage
– Not easily distinguishable from other static factory methods
9. Item 2 Premise
● Many parameter constructors or static factories do
not scale
– Hell for the client
● Telescoping constructor pattern
– Why its bad? Hard to read/write code
● Java Beans pattern
– Inconsistent path way through its construction
– Does not allow your class to be immutable. Setters!!!
10. Item 2 Solution
● Builders!!!
– Makes your class immutable. Important
– Makes it easy to read and write code
– Builders allows you to set invariants. If Invariant is not
satisfied throw IllegalArgumentException
– Builders can have multiple varargs where as constructor
only one
● “The Builder pattern is a good choice when designing
classes whose constructors or static factories would
have more than a handful of parameters"
11. Item 3
Enforce the singleton property with a private
constructor or an enum Type
12. Item 3 - Premise
● Make a class singleton
● Avoid reflection attacks on singleton classes
made singleton conventionally
– AccessibleObject.setAccessible
● Serialization making multiple copies of the
same object
13. Item3-Solution
● Have a public static final field which contains the instance
– Class declaration makes it evident, its singleton
● Have a private static field with the factory method returning the instance
– The factory API can be easily modified to make it non singleton
● Use enum to create singletons
● Have the constructor throw an exception – to solve Reflection problem
● Make all the field transient and implement a resolveObject API to resolve
serialization problem
15. Item 4 – Premise
● Want to write a class which is a group of static
methods
● Write group of methods on primitive values or
arrays. e.g: java.util.Arrays java.lang.Math
● Don't create an object where its non-sensical
to do so – Utility Classes
16. Item 4 - Solution
● Simple: Add a private constructor.
● If you don't? - A default constructor gets
generated. You can still do a
X obj = new X(); //This is bad.
● You have instantiated a class when not
required
● Positive Side Effect: Can't be subclasses
19. Solution
● String pool of-course!!!
– String s = new String(“string”);//Code smell
● Use static factory methods for object creation
– Boolean(String) //Code smell
● Reuse Mutable Objects. Assuming these objects
are not expected to be mutated
● Safe to reuse immutable objects
● Beware of auto-boxing
27. Premise
● Need to understand Memory Leaks first
● Don't misunderstand Java Garbage collector cleans
it all
– Obsolete References to blame.
– References that will never be referenced again
● Memory Leaks in caches
● Listeners and their callbacks, another culprit
– API exposes where client register a call back but no
mechanism to de-register them.
28. Solution
● Nullify obsolete references
● Don't make it a norm and use judiciously. Best
way to let variable fall out of scope
● Cache – WeakHashMap Enteries will be
removes automatically after they become
obsolete
● Store only weak references to callbacks
29. Avoid finalizers
● Unpredictable, dangerous and unnecessary
● Implementation of finalizers is JVM implementation dependent
● When finalizer will be invoked is a function of the VM's
garbage collection algorithm
● System.gc does not guarantee finalizers execute
● Performance penalty with finalizers
● Don't rely on finalizer to ensure program correctness. Your
design is flawed
● Instead
– Make use of explicit termination methods. try catch finally.