Effective Java

Effective Java

This is not a beginner’s book.

But it is one of the most important intermediate level books you are ever going to read. Seriously.

It contains many tips on how to improve your coding style, including the reasoning behind each advice. The latter is the most important since it improves the way you are actually thinking and as the result of this, the way you are writing the code.

The only drawback (currently at least) is that it has not been updated for Java 8 and lambda expressions. But it still remains a must read.

Here is a list of the rules:

 

  • 2. CREATING AND DESTROYING OBJECTS
    • 1. Use STATIC FACTORY METHODS instead of constructors
    • 2. Use BUILDERS when faced with many constructors
    • 3. Enforce the singleton property with a private constructor or an enum type
    • 4. Enforce noninstantiablillity with a private constructor
    • 5. Avoid creating objects
    • 6. Eliminate obsolete object references
    • 7. Avoid finalizers
  • 3. METHODS COMMON TO ALL OBJECTS
    • 8. Obey the general contract when overriding equals
    • 9. Always override hashCode when you override equals
    • 10. Always override toString
    • 11. Override clone judiciously
    • 12. Consider implementing Comparable
  • 4. CLASSES AND INTERFACES
    • 13. Minimize the accessibility of classes and members
    • 14. In public classes, use accessor methods, not public fields
    • 15. Minimize Mutability
    • 16. Favor composition over inheritance
    • 17. Design and document for inheritance or else prohibit it.
    • 18. Prefer interfaces to abstract classes
    • 19. Use interfaces only to define types
    • 20. Prefer class hierarchies to tagged classes
    • 21. Use function objects to represent strategies
    • 22. Favor static member classes over nonstatic
  • 5. GENERICS
    • 23. Don’t use raw types in new code
    • 24. Eliminate unchecked warnings
    • 25. Prefer lists to arrays
    • 26. Favor generic types
    • 27. Favor generic Methods
    • 28. Use bounded wildcards to increase API flexibility
    • 29. Consider typesafe heterogeneous containers
  • 6. ENUMS AND ANNOTATIONS
    • 30. Use enums instead of int constants
    • 31. Use instance fields instead of ordinals
    • 32. Use EnumSet instead of bit fields
    • 33. Use EnumMap instead of ordinal indexing
    • 34. Emulate extensible enums with interfaces
    • 35. Prefer annotations to naming patterns
    • 36. Consistently use the Override annotation
    • 37. Use marker interfaces to define types
  • 7. METHODS
    • 38. Check parameters for validity
    • 39. Make defensive copies when needed.
    • 40. Design method signatures carefully
    • 41. Use overloading judiciously
    • 42. Use varargs judiciously
    • 43. Return empty arrays or collections, not nulls
    • 44. Write doc comments for all exposed API elements
  • 8. GENERAL PROGRAMMING
    • 45. Minimize the scope of local variables.
    • 46. Prefer for-each loops to traditional for loops.
    • 47. Know and use libraries
    • 48. Avoid float and double if exact answer are required
    • 49. Prefer primitive types to boxed primitives
    • 50. Avoid Strings where other types are more appropriate
    • 51. Beware the performance of string concatenation
    • 52. Refer to objects by their interface
    • 53. Prefer interfaces to reflection
    • 54. Use native methods judiciously
    • 55. Optimize judiciously
    • 56. Adhere to generally accepted naming conventions
  • 9. EXCEPTIONS
    • 57. Use exceptions only for exceptional conditions
    • 58. Use checked exceptions for recoverable conditions and runtime exceptions for programming errors
    • 59. Avoid unnecessary use of checked exceptions
    • 60. Favor the use of standard exceptions
    • 61. Throw exceptions appropriate to the abstraction
    • 62. Document all exceptions thrown by each method
    • 63. Include failure-capture information in detail messages
    • 64. Strive for failure atomicity
    • 65. Don’t ignore exceptions
  • 10. CONCURRENCY
    • 66. Synchronize access to shared mutable data
    • 67. Avoid excessive synchronization
    • 68. Prefer executors and tasks to threads
    • 69. Prefer concurrency utilities to wait and notify
    • 70. Document thread safety
    • 71. Use lazy initialization judiciously
    • 72. Don’t depend on thread scheduler
    • 73. Avoid thread groups
  • 11. SERIALIZATION
    • 74. Implement Serializable judiciously
    • 75. Consider using a custom serialized form
    • 76. Write readObject methods defensively
    • 77. For instance control, prefer enum types to readResolve
    • 78. Consider serialization proxies instead of serialized instances

Leave a Reply