Sunday, April 19, 2015

Effective Java (Remarked) - Serialization

Item 74: Implement Serializable judiciously (design, portability, performance, scalability)

A major cost of implementing Serializable is that it decreases the flexi- bility to change a class’s implementation once it has been released. A second cost of implementing Serializable is that it increases the likeli- hood of bugs and security holes. A third cost of implementing Serializable is that it increases the testing burden associated with releasing a new version of a class. Implementing the Serializable interface is not a decision to be under- taken lightly. Classes designed for inheritance should rarely implement Serializable, and interfaces should rarely extend it. Inner classes (Item 22) should not implement Serializable. To summarize, the ease of implementing Serializable is specious. Unless a class is to be thrown away after a short period of use, implementing Serializ- able is a serious commitment that should be made with care. Extra caution is war- ranted if a class is designed for inheritance. For such classes, an intermediate design point between implementing Serializable and prohibiting it in sub- classes is to provide an accessible parameterless constructor. This design point permits, but does not require, subclasses to implement Serializable.

When use? always.

Item 75: Consider using a custom serialized form (design, portability, performance, scalability)

Do not accept the default serialized form without first considering whether it is appropriate. The default serialized form is likely to be appropriate if an object’s phys- ical representation is identical to its logical content. Even if you decide that the default serialized form is appropriate, you often must provide a readObject method to ensure invariants and security. To summarize, when you have decided that a class should be serializable (Item 74), think hard about what the serialized form should be. Use the default serialized form only if it is a reasonable description of the logical state of the object; otherwise design a custom serialized form that aptly describes the object.

When use? always.

Item 76: Write readObject methods defensively (design, portability, performance, scalability)

When an object is deserialized, it is critical to defensively copy any field containing an object reference that a client must not possess. To summarize, anytime you write a readObject method, adopt the mind-set that you are writing a public constructor that must produce a valid instance regard- less of what byte stream it is given. Do not assume that the byte stream represents an actual serialized instance. 

When use? always.

Item 77: For instance control, prefer enum types to readResolve (design, portability, performance, scalability)

To summarize, you should use enum types to enforce instance control invariants wherever possible. If this is not possible and you need a class to be both serializable and instance-controlled, you must provide a readResolve method and ensure that all of the class’s instance fields are either primitive or transient.

When use? always.

Item 78: Consider serialization proxies in stead of serialized instances (design, portability, performance, scalability)

In summary, consider the serialization proxy pattern whenever you find your- self having to write a readObject or writeObject method on a class that is not extendable by its clients. This pattern is perhaps the easiest way to robustly serialize objects with nontrivial invariants.


When use? always.

Effective Java (Remarked) - Concurrency

Item 66: Synchronize access to shared mutable data (stability)

In summary, when multiple threads share mutable data, each thread that reads or writes the data must perform synchronization. Without synchronization, there is no guarantee that one thread’s changes will be visible to another. The penalties for failing to synchronize shared mutable data are liveness and safety failures. These failures are among the most difficult to debug. 

When use? when you need to avoid dirty-reads.

Item 67: Avoid excessive synchronization (stability, performance)

As a rule, you should do as little work as possible inside synchronized regions. Obtain the lock, examine the shared data, transform it as necessary, and drop the lock. 

When use? always in threads that you do not need to avoid dirty-reads.

Item 68: Prefer executors and tasks to threads (design, stability)

The Executor Framework also has a replacement for java.util.Timer, which is ScheduledThreadPoolExecutor. While it is easier to use a timer, a scheduled thread pool executor is much more flexible. A timer uses only a single thread for task execution, which can hurt timing accuracy in the presence of long- running tasks. If a timer’s sole thread throws an uncaught exception, the timer ceases to operate. A scheduled thread pool executor supports multiple threads and recovers gracefully from tasks that throw unchecked exceptions.

When use? always.

Item 69: Prefer concurrency utilities to wait and notify (design, stability)

In summary, using wait and notify directly is like programming in “concurrency assembly language,” as compared to the higher-level language provided by java.util.concurrent. There is seldom, if ever, a reason to use wait and notify in new code. If you maintain code that uses wait and notify, make sure that it always invokes wait from within a while loop using the standard idiom. The notifyAll method should generally be used in preference to notify. If notify is used, great care must be taken to ensure liveness.

When use? always.

Item 70: Document thread safety (design, readability)

To summarize, every class should clearly document its thread safety proper- ties with a carefully worded prose description or a thread safety annotation. The synchronized modifier plays no part in this documentation. Conditionally thread-safe classes must document which method invocation sequences require external synchronization, and which lock to acquire when executing these sequences. If you write an unconditionally thread-safe class, consider using a private lock object in place of synchronized methods. This protects you against synchronization interference by clients and subclasses and gives you the flexibility to adopt a more sophisticated approach to concurrency control in a later release.

When use? always.

Item 71: Use lazy initialization judiciously (performance, stability, scalability)

In summary, you should initialize most fields normally, not lazily. If you must initialize a field lazily in order to achieve your performance goals, or to break a harmful initialization circularity, then use the appropriate lazy initialization technique. For instance fields, it is the double-check idiom; for static fields, the lazy initialization holder class idiom. For instance fields that can tolerate repeated ini- tialization, you may also consider the single-check idiom.

When use? it depends pretty of context. Is hard to define when.

Item 72: Don’t depend on the thread scheduler (design, stability, readability)

In summary, do not depend on the thread scheduler for the correctness of your program. The resulting program will be neither robust nor portable. As a corollary, do not rely on Thread.yield or thread priorities. These facilities are merely hints to the scheduler. Thread priorities may be used sparingly to improve the quality of service of an already working program, but they should never be used to “fix” a program that barely works.

When use? always.

Item 73: Avoid thread groups (design)

To summarize, thread groups don’t provide much in the way of useful functionality, and much of the functionality they do provide is flawed. Thread groups are best viewed as an unsuccessful experiment, and you should simply ignore their existence. If you design a class that deals with logical groups of threads, you should probably use thread pool executors.


When use? always.

Effective Java (Remarked) - Exceptions

Item 57: Use exceptions only for exceptional conditions (safe, stability)

The moral of this story is simple: exceptions are, as their name implies, to be used only for exceptional conditions; they should never be used for ordinary control flow. 

When use? always.

Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors (safe, stability)

Use checked exceptions for conditions from which the caller can reasonably be expected to recover.  Use runtime exceptions to indicate programming errors. Therefore, all of the unchecked throw- ables you implement should subclass RuntimeException (directly or indirectly).

When use? always.

Item 59: Avoid unnecessary use of checked exceptions (safe, stability)

Checked exceptions are a wonderful feature of the Java programming language. Unlike return codes, they force the programmer to deal with exceptional conditions, greatly enhancing reliability.

When use? always.

Item 60: Favor the use of standard exceptions (safe, stability)

One of the attributes that most strongly distinguishes expert programmers from less experienced ones is that experts strive for and usually achieve a high degree of code reuse. Finally, be aware that choosing which exception to reuse is not always an exact science, as the occasions for use in the table above are not mutually exclusive.

When use? always.

Item 61: Throw exceptions appropriate to the abstraction (safe, stability)

Where possible, the best way to deal with exceptions from lower layers is to avoid them, by ensuring that lower-level methods succeed. In summary, if it isn’t feasible to prevent or to handle exceptions from lower layers, use exception translation, unless the lower-level method happens to guarantee that all of its exceptions are appropriate to the higher level.

When use? it depends.

Item 62: Document all exceptions thrown by each method (safe, stability)

Always declare checked exceptions individually, and document precisely the conditions under which each one is thrown using the Javadoc @throws tag. In summary, document every exception that can be thrown by each method that you write. This is true for unchecked as well as checked exceptions, and for abstract as well as concrete methods. 

When use? always.

Item 63: Include failure-capture information in detail messages (safe, stability)

To capture the failure, the detail message of an exception should contain the values of all parameters and fields that “contributed to the exception.”

When use? always.

Item 64: Strive for failure atomicity (safe, stability)

Generally speaking, a failed method invocation should leave the object in the state that it was in prior to the invocation.

When use? always.

Item 65: Don’t ignore exceptions (safe, stability)

While this advice may seem obvious, it is violated often enough that it bears repeat- ing. When the designers of an API declare a method to throw an exception, they are trying to tell you something. Don’t ignore it! It is easy to ignore exceptions by surrounding a method invocation with a try statement with an empty catch block.


When use? always.

Effective Java (Remarked) - General Programming

Item 45: Minimize the scope of local variables (design, safe)

The most powerful technique for minimizing the scope of a local variable is to declare it where it is first used. Nearly every local variable declaration should contain an initializer. A final technique to minimize the scope of local variables is to keep methods small and focused. 

When use? always.

Item 46: Prefer for-each loops to traditional for loops (design, safe)

In summary, the for-each loop provides compelling advantages over the traditional for loop in clarity and bug prevention, with no performance penalty. You should use it wherever you can.

When use? always.

Item 47: Know and use the libraries (design)

To summarize, don’t reinvent the wheel. If you need to do something that seems like it should be reasonably common, there may already be a class in the libraries that does what you want. If there is, use it; if you don’t know, check. Gen- erally speaking, library code is likely to be better than code that you’d write your- self and is likely to improve over time. This is no reflection on your abilities as a programmer. Economies of scale dictate that library code receives far more atten- tion than most developers could afford to devote to the same functionality.

When use? always.

Item 48: Avoid float and double if exact answers are required (design, safe, performance)

The float and double types are designed primarily for scientific and engineering calculations. They perform binary floating-point arithmetic, which was carefully designed to furnish accurate approximations quickly over a broad range of magnitudes. They do not, however, provide exact results and should not be used where exact results are required. The float and double types are particularly ill- suited for monetary calculations because it is impossible to represent 0.1 (or any other negative power of ten) as a float or double exactly.

When use? always.

Item 49: Prefer primitive types to boxed primitives (performance)

In summary, use primitives in preference to boxed primitives whenever you have the choice. Primitive types are simpler and faster. If you must use boxed primitives, be careful! Autoboxing reduces the verbosity, but not the danger, of using boxed primitives. When your program compares two boxed primitives with the == operator, it does an identity comparison, which is almost certainly not what you want. When your program does mixed-type computations involving boxed and unboxed primitives, it does unboxing, and when your program does unboxing, it can throw a NullPointerException. Finally, when your program boxes primitive values, it can result in costly and unnecessary object creations.

When use? always.

Item 50: Avoid strings where other types are more appropriate (performance, readability)

Strings are designed to represent text, and they do a fine job of it. Because strings are so common and so well supported by the language, there is a natural tendency to use strings for purposes other than those for which they were designed. This item discusses a few things that you shouldn’t do with strings. To summarize, avoid the natural tendency to represent objects as strings when better data types exist or can be written. Used inappropriately, strings are more cumbersome, less flexible, slower, and more error-prone than other types. Types for which strings are commonly misused include primitive types, enums, and aggregate types.

When use? always.

Item 51: Beware the performance of string concatenation (performance)

The string concatenation operator (+) is a convenient way to combine a few strings into one. It is fine for generating a single line of output or for constructing the string representation of a small, fixed-size object, but it does not scale. Using the string concatenation operator repeatedly to concatenate n strings requires time quadratic in n. It is an unfortunate consequence of the fact that strings are immutable. The moral is simple: don’t use the string concatenation operator to combine more than a few strings unless performance is irrelevant. Use StringBuilder’s append method instead. Alternatively, use a character array, or process the strings one at a time instead of combining them.

When use? always.

Item 52: Refer to objects by their interfaces (design)

If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types. If you get into the habit of using interfaces as types, your program will be much more flexible.

When use? always.

Item 53: Prefer interfaces to reflection (design, performance)

In summary, reflection is a powerful facility that is required for certain sophisticated system programming tasks, but it has many disadvantages. If you are writ- ing a program that has to work with classes unknown at compile time, you should, if at all possible, use reflection only to instantiate objects, and access the objects using some interface or superclass that is known at compile time.

When use? always.

Item 54: Use native methods judiciously (design, safe, performance)

The Java Native Interface (JNI) allows Java applications to call native methods, which are special methods written in native programming languages such as C or C++. Native methods can perform arbitrary computation in native languages before returning to the Java programming language. In summary, think twice before using native methods. Rarely, if ever, use them for improved performance. If you must use native methods to access low-level resources or legacy libraries, use as little native code as possible and test it thoroughly. A single bug in the native code can corrupt your entire application.

When use? always.

Item 55: Optimize judiciously (design, performance)

To summarize, do not strive to write fast programs—strive to write good ones; speed will follow. Do think about performance issues while you’re designing systems and especially while you’re designing APIs, wire-level protocols, and persistent data formats. When you’ve finished building the system, measure its performance. If it’s fast enough, you’re done. If not, locate the source of the problems with the aid of a profiler, and go to work optimizing the relevant parts of the system. The first step is to examine your choice of algorithms: no amount of low- level optimization can make up for a poor choice of algorithm. Repeat this process as necessary, measuring the performance after every change, until you’re satisfied.

When use? always.

Item 56: Adhere to generally accepted naming conventions (design, readability)

To summarize, internalize the standard naming conventions and learn to use them as second nature. The typographical conventions are straightforward and largely unambiguous; the grammatical conventions are more complex and looser. To quote from The Java Language Specification [JLS, 6.8], “These conventions should not be followed slavishly if long-held conventional usage dictates other- wise.” Use common sense.


When use? always.

Effective Java (Remarked) - Methods

Item 38: Check parameters for validity (safe, error-prone)

To summarize, each time you write a method or constructor, you should think about what restrictions exist on its parameters. You should document these restrictions and enforce them with explicit checks at the beginning of the method body. It is important to get into the habit of doing this. The modest work that it entails will be paid back with interest the first time a validity check fails.

When use? always.

Item 39: Make defensive copies when needed (safe, error-prone, stability)

You must program defensively, with the assumption that clients of your class will do their best to destroy its invariants. In summary, if a class has mutable components that it gets from or returns to its clients, the class must defensively copy these components. If the cost of the copy would be prohibitive and the class trusts its clients not to modify the compo- nents inappropriately, then the defensive copy may be replaced by documentation outlining the client’s responsibility not to modify the affected components.

When use? always.

Item 40: Design method signatures carefully (design, safe, error-prone, readability)

Choose method names carefully. Names should always obey the standard naming conventions (Item 56). Your primary goal should be to choose names that are understandable and consistent with other names in the same package.

When use? always.

Item 41: Use overloading judiciously (design, safe, error-prone, readability, stability)

To summarize, just because you can overload methods doesn’t mean you should. You should generally refrain from overloading methods with multiple sig- natures that have the same number of parameters. In some cases, especially where constructors are involved, it may be impossible to follow this advice.

When use? always.

Item 42: Use varargs judiciously (design, safe, error-prone, readability, stability)

In summary, varargs methods are a convenient way to define methods that require a variable number of arguments, but they should not be overused. They can produce confusing results if used inappropriately.

When use? always.

Item 43: Return empty arrays or collections, not nulls (safe, error-prone, stability)

In summary, there is no reason ever to return null from an array or collection-valued method instead of returning an empty array or collection. The null-return idiom is likely a holdover from the C programming language, in which array lengths are returned separately from actual arrays. In C, there is no advantage to allocating an array if zero is returned as the length.

When use? always.

Item 44: Write doc comments for all exposed API elements (design, safe, readability)

To summarize, documentation comments are the best, most effective way to document your API. Their use should be considered mandatory for all exported API elements. Adopt a consistent style that adheres to standard conventions. Remember that arbitrary HTML is permissible within documentation comments and that HTML metacharacters must be escaped.


When use? always.

Effective Java (Remarked) - Enums and Annotations

Item 30: Use enums instead of int constants (safe, error-prone, readability)

In summary, the advantages of enum types over int constants are compelling. Enums are far more readable, safer, and more powerful. Many enums require no explicit constructors or members, but many others benefit from associating data with each constant and providing methods whose behavior is affected by this data. Far fewer enums benefit from associating multiple behaviors with a single method. In this relatively rare case, prefer constant-specific methods to enums that switch on their own values. Consider the strategy enum pattern if multiple enum constants share common behaviors.

When use? always whether you need to create a constant.

Item 31: Use instance fields instead of ordinals (safe, error-prone, readability)

Never derive a value associated with an enum from its ordinal; store it in an instance field instead.

When use? always.

Item 32: Use EnumSet instead of bit fields (safe, error-prone, readability)

In summary, just because an enumerated type will be used in sets, there is no reason to represent it with bit fields. The EnumSet class combines the conciseness and performance of bit fields with all the many advantages of enum types described in Item 30.

When use? always.

Item 33: Use EnumMap instead of ordinal indexing (safe, error-prone, readability)

Using a nested EnumMap to associate data with enum pairs. In summary, it is rarely appropriate to use ordinals to index arrays: use EnumMap instead.

When use? always.

Item 34: Emulate extensible enums with interfaces (safe, error-prone, readability)

In almost all respects, enum types are superior to the typesafe enum pattern described in the first edition of this book [Bloch01]. On the face of it, one exception concerns extensibility, which was possible under the original pattern but is not supported by the language construct.

When use? always.

Item 35: Prefer annotations to naming patterns (safe, error-prone, readability)

Prior to release 1.5, it was common to use naming patterns to indicate that some program elements demanded special treatment by a tool or framework.

When use? always.

Item 36: Consistently use the Override annotation (safe, error-prone, readability)

You should use the Override annotation on every method decla- ration that you believe to override a superclass declaration. In summary, the compiler can protect you from a great many errors if you use the Override annotation on every method declaration that you believe to override a supertype declaration, with one exception. In concrete classes, you need not annotate methods that you believe to override abstract method declarations (though it is not harmful to do so).

When use? always.

Item 37: Use marker interfaces to define types (safe, error-prone, readability)

A marker interface is an interface that contains no method declarations, but merely designates (or “marks”) a class that implements the interface as having some property. For example, consider the Serializable interface (item 11). By implementing this interface, a class indicates that its instances can be written to an ObjectOutputStream (or “serialized”). Marker interfaces define a type that is implemented by instances of the marked class; marker annotations do not.


When use? when you need to mark yours classes to do something, like a list or something like that.

Effective Java (Remarked) - Generics

Item 23: Don’t use raw types in new code (stability, security, error-prone)

In summary, using raw types can lead to exceptions at runtime, so don’t use them in new code. They are provided only for compatibility and interoperability with legacy code that predates the introduction of generics.

When use? always.

Item 24: Eliminate unchecked warnings (stability, error-prone)

If you can’t eliminate a warning, and you can prove that the code that provoked the warning is typesafe, then (and only then) suppress the warning with an @SuppressWarnings("unchecked") annotation. In summary, unchecked warnings are important. Don’t ignore them. Every unchecked warning represents the potential for a ClassCastException at run- time.

When use? always.

Item 25: Prefer lists to arrays (design, maintainability)

Generally speaking, arrays and generics don’t mix well. If you find yourself mixing them and getting compile-time errors or warnings, your first impulse should be to replace the arrays with lists. In summary, arrays and generics have very different type rules. Arrays are covariant and reified; generics are invariant and erased. As a consequence, arrays provide runtime type safety but not compile-time type safety and vice versa for generics.

When use? it depends of the context. But when you work with objects, prefer lists.

Item 26: Favor generic types (design)

In summary, generic types are safer and easier to use than types that require casts in client code. When you design new types, make sure that they can be used without such casts. This will often mean making the types generic. Generify your existing types as time permits. This will make life easier for new users of these types without breaking existing clients.

When use? always whatever if you work in a API or a consumer code.

Item 27: Favor generic methods (design)

In summary, generic methods, like generic types, are safer and easier to use than methods that require their clients to cast input parameters and return values. Like types, you should make sure that your new methods can be used without casts, which will often mean making them generic. And like types, you should generify your existing methods to make life easier for new users without breaking existing clients.

When use? always whatever if you work in a API or a consumer code.

Item 28: Use bounded wildcards to increase API flexibility (design)

In summary, using wildcard types in your APIs, while tricky, makes the APIs far more flexible. If you write a library that will be widely used, the proper use of wildcard types should be considered mandatory. Remember the basic rule: producer-extends, consumer-super (PECS). And remember that all comparables and comparators are consumers.

When use? always.

Item 29: Consider type safe heterogeneous containers (safe, error-prone)

In summary, the normal use of generics, exemplified by the collections APIs, restricts you to a fixed number of type parameters per container. You can get around this restriction by placing the type parameter on the key rather than the container.


When use? always.

Friday, April 17, 2015

Effective Java (Remarked) - Classes and Interfaces

Item 13: Minimize the accessibility of classes and members (design, stability)

The single most important factor that distinguishes a well-designed module from a poorly designed one is the degree to which the module hides its internal data and other implementation details from other modules. To summarize, you should always reduce accessibility as much as possible. After carefully designing a minimal public API, you should prevent any stray classes, interfaces, or members from becoming a part of the API. With the exception of public static final fields, public classes should have no public fields. Ensure that objects referenced by public static final fields are immutable.

When use? always, whitout exception.

Item 14: In public classes, use accessor methods, not public fields (design, stability)

Because the data fields of such classes are accessed directly, these classes do not offer the benefits of encapsulation (Item 13). You can’t change the representation without changing the API, you can’t enforce invariants, and you can’t take auxiliary action when a field is accessed. In summary, public classes should never expose mutable fields. It is less harmful, though still questionable, for public classes to expose immutable fields. It is, however, sometimes desirable for package-private or private nested classes to expose fields, whether mutable or immutable.

When use? always.

Item 15: Minimize mutability (design, performance, stability)

An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object. The Java platform libraries contain many immutable classes, including String, the boxed primitive classes, and BigInteger and BigDecimal. There are many good reasons for this: Immutable classes are easier to design, implement, and use than mutable classes. To summarize, resist the urge to write a set method for every get method. Classes should be immutable unless there’s a very good reason to make them mutable. Immutable classes provide many advantages, and their only disadvantage is the potential for performance problems under certain circumstances. You should always make small value objects, such as PhoneNumber and Complex, immutable.

When use? always, do it judicially with ORM classes.

Item 16: Favor composition over inheritance (design)

To summarize, inheritance is powerful, but it is problematic because it violates encapsulation. It is appropriate only when a genuine subtype relationship exists between the subclass and the superclass. Even then, inheritance may lead to fragility if the subclass is in a different package from the superclass and the superclass is not designed for inheritance. To avoid this fragility, use composition and forwarding instead of inheritance, especially if an appropriate interface to implement a wrapper class exists. Not only are wrapper classes more robust than subclasses, they are also more powerful.

When use? always as possible.

Item 17: Design and document for inheritance or else prohibit it (design)

If a concrete class does not implement a standard interface, then you may inconvenience some programmers by prohibiting inheritance. If you feel that you must allow inheritance from such a class, one reasonable approach is to ensure that the class never invokes any of its overridable methods and to document this fact. In other words, eliminate the class’s self-use of overridable methods entirely. In doing so, you’ll create a class that is reasonably safe to subclass. Overriding a method will never affect the behavior of any other method.

When use? it depends, especially of the context. But try to keep your methods and attributes final, whenever possible.

Item 18: Prefer interfaces to abstract classes (design)

To summarize, an interface is generally the best way to define a type that permits multiple implementations. An exception to this rule is the case where ease of evolution is deemed more important than flexibility and power. Under these circumstances, you should use an abstract class to define the type, but only if you understand and can accept the limitations. If you export a nontrivial interface, you should strongly consider providing a skeletal implementation to go with it. Finally, you should design all of your public interfaces with the utmost care and test them thoroughly by writing multiple implementations.

When use? always, except for factored behaviour.

Item 19: Use interfaces only to define types (design)

In summary, interfaces should be used only to define types. They should not be used to export constants. In summary, tagged classes are seldom appropriate. If you’re tempted to write a class with an explicit tag field, think about whether the tag could be eliminated and the class replaced by a hierarchy. When you encounter an existing class with a tag field, consider refactoring it into a hierarchy.

When use? it depends, but generally speaking, yes, do it.

Item 20: Prefer class hierarchies to tagged classes (design)

Occasionally you may run across a class whose instances come in two or more flavors and contain a tag field indicating the flavor of the instance.In summary, tagged classes are seldom appropriate. If you’re tempted to write a class with an explicit tag field, think about whether the tag could be eliminated and the class replaced by a hierarchy. When you encounter an existing class with a tag field, consider refactoring it into a hierarchy.

When use? always.

Item 21: Use function objects to represent strategies (design)

To summarize, a primary use of function pointers is to implement the Strategy pattern. To implement this pattern in Java, declare an interface to represent the strategy, and a class that implements this interface for each concrete strategy. When a concrete strategy is used only once, it is typically declared and instantiated as an anonymous class. When a concrete strategy is designed for repeated use, it is generally implemented as a private static member class and exported in a public static final field whose type is the strategy interface.

When use? always.

Item 22: Favor static member classes over non static (design, performance)

If you declare a member class that does not require access to an enclosing instance, always put the static modifier in its declaration, making it a static rather than a nonstatic member class.


When use? always. It is a good way to obtain performance.

Thursday, April 16, 2015

Effective Java (Remarked) - Methods Common to All Objects

Item 8: Obey the general contract when overriding equals (performance, stability)

Overriding the equals method seems simple, but there are many ways to get it wrong, and consequences can be dire. The easiest way to avoid problems is not to override the equals method, in which case each instance of the class is equal only to itself. When you override the equals method, you must adhere to its general contract: Reflexive, Symmetric, Transitive and Consistent.

When use? especially in ORM classes.

Item 9: Always override hashCode when you override equals (performance, stability)

A common source of bugs is the failure to override the hashCode method. You must override hashCode in every class that overrides equals. Failure to do so will result in a violation of the general contract for Object.hashCode, which will prevent your class from functioning properly in conjunction with all hash-based collections, including HashMap, HashSet, and Hashtable.

When use? always you override equals.

Item 10: Always override toString (readability)

When practical, the toString method should return all of the interesting information contained in the object. One important decision you’ll have to make when implementing a toString method is whether to specify the format of the return value in the documentation.

When use? always you need to get class information human-friendly.

Item 11: Override clone judiciously (performance, stability, readability)

To recap, all classes that implement Cloneable should override clone with a public method whose return type is the class itself. This method should first call super.clone and then fix any fields that need to be fixed.

When use? to copy objects using specific attributes.

Item 12: Consider implementing Comparable (performance, stability, readability)

By implementing Comparable, a class indicates that its instances have a natural ordering. By implementing Comparable, you allow your class to interoperate with all of the many generic algorithms and collection implementations that depend on this interface.


When use? especially in ORM classes.

Wednesday, April 15, 2015

Effective Java (Remarked) - Creating and Destroying Objects

Item 1: Consider static factory methods instead of constructors (readability)

One advantage of static factory methods is that, unlike constructors, they have names. A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked. A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type. A fourth advantage of static factory methods is that they reduce the verbosity of creating parameterized type instances. 

When use? to create a new object with more accuracy rather a constructor.

Item 2: Consider a builder when faced with many constructor parameters (readability)

It is a good way to create objects especially with optional arguments. Static factories and constructors share a limitation: they do not scale well to large numbers of optional parameters. In summary, the Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if most of those parameters are optional.

When use? to build a object with or without a optional parameter.

Item 3: Enforce the singleton property with a private constructor or an enum type (stability)

A singleton is simply a class that is instantiated exactly once. This approach is functionally equivalent to the public field approach, except that it is more concise, provides the serialization machinery for free, and provides an ironclad guarantee against multiple instantiation, even in the face of sophisticated serialization or reflection attacks.

When use? singleton pattern is needs.

Item 4: Enforce noninstantiability with a private constructor (stability)

Attempting to enforce noninstantiability by making a class abstract does not work. The class can be subclassed and the subclass instantiated. Furthermore, it misleads the user into thinking the class was designed for inheritance (Item 17). There is, however, a simple idiom to ensure noninstantiability. A default constructor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor.

When use? utility noninstantiate class.

Item 5: Avoid creating unnecessary objects (performance)

It is often appropriate to reuse a single object instead of creating a new function- ally equivalent object each time it is needed. Reuse can be both faster and more stylish. An object can always be reused if it is immutable (Item 15). Note that the penalty for reusing an object when defensive copying is called for is far greater than the penalty for needlessly creating a duplicate object. Failing to make defensive copies where required can lead to insidious bugs and security holes; creating objects unnecessarily merely affects style and performance.

When use? all the time.

Item 6: Eliminate obsolete object references (performance, stability)

Because memory leaks typically do not manifest themselves as obvious failures, they may remain present in a system for years. They are typically discovered only as a result of careful code inspection or with the aid of a debugging tool known as a heap profiler. Therefore, it is very desirable to learn to anticipate problems like this before they occur and prevent them from happening.

When use? all the time.

Item 7: Avoid finalizers (performance, stability)

Finalizers are unpredictable, often dangerous, and generally unnecessary.
Their use can cause erratic behavior, poor performance, and portability problems. In summary, don’t use finalizers except as a safety net or to terminate noncritical native resources. In those rare instances where you do use a finalizer, remember to invoke super.finalize. If you use a finalizer as a safety net, remember to log the invalid usage from the finalizer. Lastly, if you need to associate a finalizer with a public, nonfinal class, consider using a finalizer guardian, so finalization can take place even if a subclass finalizer fails to invoke super.finalize.


When use? all the time.