28 Dec 2020
Chanpter 2 : Methods Common to All Objects
Item 10
You can find the longer version of this summary here.
equals
- Should it be implemented?
- Is it an inherited class?
- Implement hashCode
implementation method
The equals method implements an equivalence relation (Reflexive, Symmetric, Transitive, Consistent), null check and Liskov subsitution principle
- Determine whether you are yourself with
==
- Check type with
instanceOf
- Type casting
- Check the ‘Core’ field
- in the order of the probability of being different and the fastest comparison
hashCode
- If
equals is true, hashCode is always true. If equals is false, hashCode is not always false
- Generate hash code with fields of
equals.
- Don’t publish rules for generating hash code.
toString
- Ideally, it should be a string that perfectly describes the object itself.
- Return all key information the object has.
Cloneable
- Don’t implement
Cloneable. Instead, implement a copy factory, a copy constructor.
Copy constructor
public Yum(Yum yum) { ... };
Copy factory
public static Yum newInstance(Yum yum) { ... };
Comparable
- Like
equals, Reflexive, Symmetric and Transitive must be met.
- An inherited object cannot implement a perfect
compareTo.
- Sorted collections use
compareTo() for equality comparison.
- Don’t use relational operators (<, >), use static compare methods or comparators.
22 Dec 2020
You can find the shorter version of this summary here.
Item 1: Consider static factory methods instead of constructors
Pros:
- They have names
- Better readability (e.g. BigInteger’s static factory method
BigInteger.probablePrime)
- Constructors have a signature conflict if parameter types and orders are the same - because all constructors are considered to have the same method name, but factory methods do not have this problem.
- They are not required to create a new object each time they are invoked.
- Can cache instances, or even never create an instance (e.g.
Boolean.valueOf)
- They can return a subtype of their return type.
- The returned class can vary from call to call as a function of the input parameters.
- Better encapsulation (e.g., OpenJDK’s
EnumSet has two concrete implementations (Regular and Jumbo) but clients do not have to care about them)
- The class of the returned object need not exist when the class containing the method is written (i.e., it can be injected later, such as using prototype pattern)
Cons:
- Classes without public or protected constructors cannot be subclassed.
- It is hard for programmers to find the static factory methods, compared to constructors - they do not stand out unless explicitly highlighted.
- Some common names include:
from, of, valueOf, getInstance, create, newInstance etc.
Item 2: Consider a builder when faced with many constructor parameters
Constructors with too many parameters or options (telescoping constructor pattern), are hard to use and maintain. Consider a builder pattern to replace them. JavaBeans pattern could be considered as an alternative, but they preclude the possibility of making a class immutable.
Pros:
- Better readability
- Can ensure immutability
- Can be used repeatedly
Cons:
- Builder itself has a performance cost
- Builder pattern is more verbose. (it should be considered when there are enough parameters to make it worthwhile, say four or more.)
Item 3: Enforce the singleton property with a private constructor or an enum type
Notes:
In this item, some non-lazy singleton generation techniques are illustrated with private constructor pattern or enum pattern. This is a well-studied topic, and the techniques include large code snippets, so I’ll not illustrate them in detail here.
The author encourages using the enum type as below.
This approach may feel a bit unnatural, but a single-element enum type is often the best way to implement a singleton.
Item 4: Enforce noninstantiability with a private constructor
When you have a utility class that should not be instantiated, provide a private constructor to prevent autogenerated public default constructor.
Pros:
- The instantiation is programmatically blocked.
- The class cannot be subclassed.
Cons:
- The class cannot be subclassed. (It is good and bad at the same time)
Item 5: Prefer dependency injection to hardwiring resources
Long story short, use interfaces instead of concrete classes (decouple classes) and inject dependencies instead of hardcoding them. If the code depends on the interface, the implementation’s change will affect the client much less than depending on the concrete implementations.
22 Dec 2020
Chanpter 1 : Creating and Destroying Objects
Item 1~5
You can find the longer version of this summary here.
Object creation patterns
- Default constructor
- Static factory method pattern
- Telescoping constructor pattern
- Java Beans pattern
- Builder pattern
Things to consider before object creation
- Will it be used as a singleton?
- Is it a utility class?
- Is it a class that implements an interface?
- Will it allow inheritance?
- How many parameters are required?
Item 6~9
You can find the longer version of this summary here.
Efficient object management
- Reuse immutable objects
- Always minimize the scope
- Watch out for memory leaks in the following situations
- Class that directly manages memory
- Use of cache (considering WeakHashMap)
- Listener, Callback
- Don’t use object destructor
finalizer, cleaner
- As an alternative, use
AutoCloseable + try-with-resources syntax