-
Creating and Destroying Objects
- Consider static factory method instead of constructor
- Consider a builder when faced with many constructor parameters
- Enforce the singleton property with a private constructor or an enum type
- Enforce noninstantiability with a private constructor
- Avoid creating unnecessary objects
- Eliminate obsolete object references
- Avoid finalizers
-
Method Common to All Object
- Obey the general contract when overriding equals
- Always override hashCode when you override equals
- Always override toString
- Override clone judiciously
- Consider implementing Comparable
-
Classes and Interfaces
- Minimize the accessibility of the classes and members
- In public classes, use public accessor method, not public fields
- Minimize mutability
- Favor composition over inheritance
- Design or document inheritance or else prohibit it
- Prefer interfaces to abstract classes
- Use interfaces only to define types
- Prefer class hierarchies to tagged classes
- Use function objects to represent strategies
- Favor static member classes over nonstatic
-
Generics
- Don't use raw types in new code
- Eliminate unchecked warnings
- Prefer lists to arrays
- Favor generic types
- Favor generic methods
- Use bounded wildcards to increase API flexibility
- Consider typesafe heterogenous containers
-
Enums and Annotations
- Use enum instead of int constants
- Use instance fields instead of ordinals
- Use EnumSet instead of bit fields
- Use EnumMap instead of ordinal indexing
- Emulate extensible enums with interfaces
- Prefer annotations to naming pattern
- Use marker interface to define types
-
Methods
- Check parameters for validity
- Make defensive copy when needed
- Design method signatures carefully
- Use overloading judiciously
- Use varargs judiciously
- Return empty arrays or collection, not null
- Write doc comments for all exposed API elements
-
General Programming
- Minimize the scope of local variables
- Prefer for-each loops to traditional for loops
- Know and use the libraries
- Avoid use float and double if exact answers are required
- Prefer primitive types to boxed primitives
- Avoid strings when other types are more appropriate
- Beware of the performance of string concatenation
- Refer to objects by their interfaces
- Prefer interfaces to reflection
- Use native methods judiciously
- Optimize judiciously
- Adhere to generally accepted naming conventions
-
Exceptions
- Use exceptions only for exceptional condition
- Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
- Avoid unnecessary use of checked exceptions
- Favor the use of standard exceptions
- Throw exceptions appropriate to the abstraction
- Document all the exception thrown by each method
- Include failure-capture information in detail messages
- Strive for failure atomicity
- Don't ignore exceptions
-
Concurrency
- Synchronize access to shared mutable data
- Prefer executors and tasks to threads
- Prefer concurrent utilities to wait and notify
- Document thread safety
- Use lazy initialization judiciously
- Don't depend on thread scheduler
- Avoid thread group
-
Serialization
- Implement Serializable judiciously
- Consider use a custom serialized form
- Write readObject methods defensively
- For instance control, prefer enum types to readResolve
- Consider serialization proxies instead of serialized instances