Effective Java – Part 6

Chapter 10. Serialization

Item 54: Implement Serializable judiciously
Implementing Serializable is that it decreases the flexibility to change a class’s implementation once it has been released. If you accept the default serialized form and later change the class’s internal representation,an incompatible change in the serialized form may result.
You should carefully design a high-quality serialized form that you are willing to live with for the long haul (Item 55).
Every serializable class has a unique identification number associated with it.
Implementing Serializable increases the likelihood of bugs and security holes.
Relying on the default deserialization mechanism can easily leave objects open to invariant corruption and illegal access (Item 56).
Implementing Serializable increases the testing burden associated with releasing a new version of a class.
Implementing the Serializable interface is not a decision to be undertaken lightly.
Classes designed for inheritance (Item 15) should rarely implement Serializable, and interfaces should rarely extend it.
Consider providing a parameterless constructor on nonserializable classes designed for inheritance.
Inner classes (Item 18) should rarely, if ever, implement Serializable.

Item 55:Consider using a custom serialized form
Do not accept the default serialized form without first considering whether it is appropriate.The ideal serialized form of an object contains only the logical data represented by the object.The default serialized form is likely to be appropriate if an object’s physical 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.

Using the default serialized form when an object’s physical representation differs substantially from its logical data content has four disadvantages:

  1. It permanently ties the exported API to the internal representation.
  2. It can consume excessive space.
  3. It can consume excessive time.
  4. It can cause stack overflows.

If all instance fields are transient, it is technically permissible to dispense with invoking defaultWriteObject and defaultReadObject, but it is not recommended.
Regardless of what serialized form you choose, declare an explicit serial version UID in every serializable class you write.

Item 56:Write readObject methods defensively
When an object is deserialized, it is critical to defensively copy any field containing an object reference that a client must not possess.
Guidelines for writing a bulletproof readObject method:

  • For classes with object reference fields that must remain private, defensively copy each object that is to be stored in such a field. Mutable components of immutable classes fall into this category.
  • For classes with invariants, check invariants and throw an InvalidObjectException if a check fails. The checks should follow any defensive copying.
  • If an entire object graph must be validated after it is deserialized, the ObjectInputValidation interface should be used.
  • Do not invoke any overridable methods in the class, directly or indirectly.

The readResolve method may be used as an alternative to a defensive readObject method.

Item 57: Provide a readResolve method when necessary
If the class of an object being deserialized defines a readResolve method with the proper declaration, this method is invoked on the newly created object after it is deserialized. A readResolve method is necessary not only for singletons, but for all other instance controlled classes. A second use for the readResolve method is as a conservative alternative to the defensive readObject method recommended in Item 56. The accessibility of the readResolve method is significant.

Leave a Comment

Effective Java – Part 5

Chapter 8. Exceptions

Item 39:Use exceptions only for exceptional conditions
A well-designed API must not force its client to use exceptions for ordinary control flow. Provide state-testing method or distinguished return value for state-dependent methods. A state-testing method is mildly preferable to a distinguished return value

Item 40:Use checked exceptions for recoverable conditions and run-time exceptions for programming errors
Use checked exceptions for conditions from which the caller can reasonably be expected to recover.Use run-time exceptions to indicate programming errors. There is a strong convention that errors are reserved for use by the JVM to indicate resource deficiencies, invariant failures, or other conditions that make it impossible to continue execution. It’s best not to implement any new Error subclasses. Checked exceptions should provide methods to furnish information that could help callers to recover.

Item 41:Avoid unnecessary use of checked exceptions
Overuse of checked exceptions can make an API far less pleasant to use.One technique for turning a checked exception into an unchecked exception is to break the method that throws the exception into two methods, the first of which returns a boolean indicating whether the exception would be thrown.

Item 42:Favor the use of standard exceptions
Exceptions are no exception to the general rule that code reuse is good. Reuse must be based on semantics, not just on name.

Most commonly used exceptions are:
IllegalArgumentException – Parameter value is inappropriate.
IllegalStateException – Object state is inappropriate for method invocation.
NullPointerException – Parameter value is null where prohibited
IndexOutOfBoundsException – Index parameter value is out of range
ConcurrentModificationException – Concurrent modification of object has been detected where prohibited.
UnSupportedOperationException – Object does not support method

Item 43: Throw exceptions appropriate to the abstraction
Higher layers should catch lower-level exceptions and, in their place, throw exceptions that are explainable in terms of the higher-level abstraction. While exception translation is superior to mindless propagation of exceptions from lower layers, it should not be overused.

Item 44:Document all exceptions thrown by each method
Always declare checked exceptions individually, and document precisely the conditions under which each one is thrown using the Javadoc @throws tag.
Use the Javadoc @throws tag to document each unchecked exception that a method can throw, but do not use the throws keyword to include unchecked exceptions in the method declaration. If an exception is thrown by many methods in a class for the same reason, it is acceptable to document the exception in the class’s documentation comment rather than documenting it individually for each method.

Item 45:Include failure-capture information in detail messages
To capture the failure, the string representation of an exception should contain the values of all parameters and fields that “contributed to the exception”.
One way to ensure that exceptions contain adequate failure-capture information in their string representations is to require this information in their constructors in lieu of a string detail message.

Item 46:Strive for </vetbfailure atomicity
Generally speaking, a failed method invocation should leave the object in the state that it was in prior to the invocation. A method with this property is said to be failure atomic.

Item 47:Don’t ignore exceptions
An empty catch block defeats the purpose of exceptions, which is to force you to handle exceptional conditions. At the very least, the catch block should contain a comment explaining why it is appropriate to ignore the exception.

Chapter 9. Threads

Item 48: Synchronize access to shared mutable data
The synchronized keyword ensures that only a single thread will execute a statement or block at a time.Not only does synchronization prevent a thread from observing an object in an inconsistent state, but it also ensures that objects progress from consistent state to consistent state by an orderly sequence of state transitions that appear to execute sequentially. Every thread entering a synchronized method or block sees the effects of all previous state transitions controlled by the same lock.

Synchronization is required for reliable communication between threads as well as for mutual exclusion.The double-check idiom for lazy initialization is broken!The initialize-on-demand holder class idiom is appropriate for use when a static field is expensive to initialize and may not be needed, but will be used intensively if it is needed.

Whenever multiple threads share mutable data, each thread that reads or writes the data must obtain a lock.


The use of the volatile modifier constitutes a viable alternative to ordinary synchronization under certain circumstances, but this is an advanced technique

Item 49: Avoid excessive synchronization
To avoid the risk of deadlock, never cede control to the client within a synchronized method or block.As a rule, you should do as little work as possible inside synchronized regions. If you’re writing a class that will be used heavily in circumstances requiring synchronization and also in circumstances where synchronization is not required, a reasonable approach is to provide both synchronized (thread-safe) and unsynchronized (thread-compatible) variants.

Item 50: Never invoke wait outside a loop
Always use the wait loop idiom to invoke the wait method.If all of the threads vying for special status are logically equivalent, then all you have to do is carefully use notify instead of notifyall.If, however, only some of the waiting threads are eligible for special status at any given time, then you must use a pattern known as Specific Notification [Cargill96, Lea99].

Item 51: Don’t depend on the thread scheduler
Any program that relies on the thread scheduler for its correctness or performance is likely to be nonportable. The best way to write a robust, responsive, portable multithreaded application is to ensure that there are few runnable threads at any given time. The main technique for keeping the number of runnable threads down is to have each thread do a small amount of work and then wait for some condition using Object.wait or for some time to elapse using Thread.sleep. Threads should not busy-wait. Resist the temptation to “fix” the program by putting in calls to Thread.yield The only use that most programmers will ever have for Thread.yield is to artificially increase the concurrency of a program during testing.

Thread priorities are among the least portable features of the Java platform.

Item 52: Document thread safety The presence of the synchronized modifier in a method declaration is an implementation detail, not a part of the exported API.Its presence does not reliably indicate that a method is thread safe; it is subject to change from release to release.
To enable safe multithreaded use, a class must clearly document in prose the level of thread safety that it supports. Different level of thread safety – immutable, thread-safe, conditionally thread-safe, thread-compatible, thread-hostile.
Using internal objects for locking is particularly suited to classes designed for inheritance.

Item 53: Avoid thread groups
Thread groups don’t provide much in the way of useful functionality, and much of the functionality they do provide is flawed.
The ThreadGroup.uncaughtException method is automatically invoked when a thread in the group throws an uncaught exception.You may occasionally wish to override this implementation, for example, to direct the stack trace to an application-specific log.

Leave a Comment

Effective Java – Part 4

Chapter 5. Substitutes for C Constructs

Item 19: Replace structures with classes
The C struct construct was omitted from the Java programming language because a class does everything a structure does and more.

Item 20: Replace unions with class hierarchies
A structure containing a union and a tag is sometimes called a discriminated union.
A discriminated union is really just a pallid imitation of a class hierarchy.
A class hierarchy provides type safety, simple and clear coding, extensibility and flexibility.

Item 21: Replace enum constructs with classes

Item 22: Replace function pointers with classes and interfaces
Function pointers were omitted from the Java programming language because object references can be used to provide the same functionality
The primary use of C’s function pointers is to implement the Strategy pattern.To implement this pattern in the Java programming language, declare an interface to represent the strategy and a class that implements this interface for each concrete strategy.

Chapter 6. Methods

Item 23: Check parameters for validity
Detect errors as soon as possible after they occur.
Clearly document all such restrictions on parameters and enforce them with checks at the beginning of the method body.
For public methods, use the Javadoc @throws tag to document the exception that will be thrown if a restriction on parameter values is violated (Item 44).
Nonpublic methods should generally check their parameters using assertions rather than normal checks.
It is particularly important to check the validity of parameters that are not used by a method but are stored away for later use.
It is very important to check the validity of parameters to constructors to prevent the construction of an object that violates class invariants.
An important exception is the case in which the validity check would be expensive or impractical and the validity check is performed implicitly in the process of doing the computation.
Use the exception translation idiom described in Item 43 to translate the natural exception into the correct one.
You should design methods to be as general as it is practical to make them.

Item 24: Make defensive copies when needed
You must program defensively with the assumption that clients of your class will do their best to destroy its invariants.
Defensive copies are made before checking the validity of the parameters (Item 23), and the validity check is performed on the copies rather than on the originals.
Do not use the clone method to make a defensive copy of a parameter whose type is subclassable by untrusted parties.
Return defensive copies of mutable internal fields.

Item 25: Design method signatures carefully
Choose method names carefully.
Don’t go overboard in providing convenience methods. When in doubt, leave it out.
Avoid long parameter lists.Long sequences of identically typed parameters are especially harmful.
For parameter types, favor interfaces over classes.
Use function objects (Item 22) judiciously.

Item 26: Use overloading judiciously
The choice of which overloading to invoke is made at compile time.
Selection among overloaded methods is static, while selection among overridden methods is dynamic.
Avoid confusing uses of overloading.A safe, conservative policy is never to export two overloadings with the same number of parameters.

Item 27: Return zero-length arrays, not nulls
There is no reason ever to return null from an array-valued method instead of returning a zero-length array

Item 28: Write doc comments for all exposed API elements
The doc comment for a method should describe succinctly the contract between the method and its client.
Methods should document preconditions, postconditions and any side effects

Chapter 7. General Programming

Item 29: Minimize the scope of local variables
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.
Kep methods small and focused.

Item 30: Know and use the libraries
Don’t reinvent the wheel
By using a standard library, you take advantage of the knowledge of the experts who wrote it and the experience of those who used it before you.
Additions in Java 1.4 – java.util.regex, java.util.prefs, java.nio, java.util.LinkedHashSet, LinkedHashMap, IdentityHashMap

Item 31: Avoid float and double if exact answers are required
The float and double types are particularly ill-suited for monetary calculations.
If the quantities don’t exceed nine decimal digits, you can use ; if they don’t exceed eighteen digits, you can use . If the quantities int long exceed eighteen digits, you must use BigDecimal

Item 32: Avoid strings where other types are more appropriate
Strings are poor substitutes for other value types, enumerated types, aggregate types and capabilities.

Item 33: Beware the performance of string concatenation
Don’t use the string concatenation operator to combine more than a few strings unless performance is irrelevant. Use StrinfBuffer’s method instead.

Item 34: Refer to objects by their interfaces
If appropriate interface types exist, 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.
It is entirely appropriate to refer to an object by a class rather than an interface if no appropriate interface exists.

Item 35: Prefer interfaces to reflection
Reflection is a powerful facility that is required for certain sophisticated system programming tasks, but it has many disadvantages.
If you are writing 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.

Item 36: Use native methods judiciously
As of release 1.3, it is rarely advisable to use native methods for improved performance.

Item 37: Optimize judiciously
Don’t sacrifice sound architectural principles for performance.
Strive to avoid design decisions that limit performance.
Consider the performance consequences of your API design decisions.
Measure performance before and after each attempted optimization.

Item 38: Adhere to generally accepted naming conventions

Comments off

Effective Java – Part 3

Chapter 4. Classes and Interfaces

Item 12: Minimize the accessibility of classes and members
The rule of thumb is that you should make each class or member as inaccessible as possible. 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.

A protected member is part of the class’s exported API and must be supported forever. The need for protected members should be relatively rare.
If a method overrides a superclass method, it is not permitted to have a lower access level in the subclass than it does in the superclass.
It is nearly always wrong to have public static final array field.

Item 13: Favor immutability
Classes should be immutable unless there’s a very good reason to make them mutable. Immutable classes are easier to design, implement, and use than mutable classes. They are less prone to error and are more secure. Immutable objects are inherently thread-safe; they require no synchronization.

Not only can you share immutable objects, but you can share their internals. Immutable objects make great building blocks for other objects.

The only real disadvantage of immutable classes is that they require a separate object for each distinct value.

To make a class immutable:

  • Don’t provide any methods that modify the object.
  • Ensure that no methods may be overridden.
  • Make all fields final.
  • Make all fields private.
  • Ensure exclusive access to any mutable components.

If a class cannot be made immutable, you should still limit its mutability as much as possible.

Item 14: Favor composition over inheritance
Unlike method invocation, inheritance breaks encapsulation. Inheritance is appropriate only when a genuine subtype relationship exists between the subclass and the superclass.Use composition and forwarding instead of inheritance, especially if an appropriate interface to implement a wrapper class exists. Wrapper classes are not suited for use in callback frameworks

Item 15: Design and document for inheritance or else prohibit it
The class must document precisely the effects of overriding any method. For effective inheritance, a class may have to provide hooks into its internal workings in the form of judiciously chosen protected methods or,in rare instances, protected fields.
Constructors must not invoke overridable methods, directly or indirectly. Neither clone nor readObject may invoke an overridable method, directly or indirectly. readResolve and writeReplace method should be protected instead of private if a Serializable class is designed for inheritance.
Two ways to prohibit subclasing – declare the class final or make all constructors private.

Item 16: Prefer interfaces to abstract classes
Existing classes can be easily retrofitted to implement a new interface.
Interfaces are ideal for defining mixins.A mixin is a type that a class can implement in addition to its “primary type” to declare that it provides some optional behavior.
Interfaces allow the construction of nonhierarchical type frameworks. Interfaces enable safe, powerful functionality enhancements via the wrapper class idiom (Item 14). You can combine the virtues of interfaces and abstract classes by providing an abstract skeletal implementation class to go with each nontrivial interface that you export.

It is far easier to evolve an abstract class than it is to evolve an interface.Design all of your public interfaces with the utmost care and test them thoroughly by writing multiple implementations

Item 17: Use interfaces only to define types

The constant interface pattern is a poor use of interfaces. To export constants, define them in the classes, or interface or use enumerated type or utility classes.

Item 18: Favor static member classes over nonstatic

There are four kinds of nested classes: static member classes, nonstatic member classes, anonymous classes, and local classes.All but the first kind are
known as inner classes.

One common use of a nonstatic member class is to define an Adapter [Gamma98, p.139] that allows an instance of the outer class to be viewed as an instance of some unrelated class.
If you declare a member class that does not require access to an enclosing instance,remember to put the static modifier in the declaration,
Assuming the class belongs inside a method, if you need to create instances from only one location and there is a preexisting type that characterizes the class, make it an anonymous class; otherwise, make it a local class.

Leave a Comment

Effective Java – Part 2

Second part of the summary based on Effective Java.

Chapter 3. Methods Common to All Objects

Item 7: Obey the general contract when overriding equals

Do not override equals if any of the following is true:

  1. Each instance of the class is inherently unique
  2. You don’t care whether the class provides a “logical equality” test
  3. A superclass has already overridden equals, and the behavior inherited from the superclass is appropriate for this class
  4. The class is private or package-private, and you are certain that its equals method will never be invoked.

Typseafe Enums do not require equals method to be overridden.
equals method implements an equivalence relation.
There is simply no way to extend an instantiable class and add an aspect while preserving the equals contract.
A workaround is to use composition (item 14).

Recipe for a high quality equals method:

  1. Use the == operator to check if the argument is a reference to this object
  2. Use the instanceof operator to check if the argument is of the correct type.
  3. Cast the argument to the correct type.
  4. For each “significant” field in the class, check to see if that field of the argument matches the corresponding field of this object.
  5. Ask yourself three questions: Is it symmetric, is it transitive, and is it consistent?
  6. Don’t try to be too clever.
  7. Don’t write an equals method that relies on unreliable resources.

Don’t substitute another type for Object in the equals declaration.

Item 8: Always override hashCode when you override equals
Equal objects must have equal hash codes.
Do not be tempted to exclude significant parts of an object from the hash code computation to improve performance.

Item 9: Always override toString
Providing a good toString implementation makes your class much more pleasant to use.
When practical, the toString method should return all of the interesting information contained in the object,
Whether or not you decide to specify the format, you should clearly document your intentions.
It is always a good idea to provide programmatic access to all of the information contained in the value returned by toString.

Item 10: Override clone judiciously
All classes that implement Cloneable should override clone with a public method.This public method should first call super.clone and then fix any fields that need fixing.
The Cloneable interface was intended as a mixin interface (Item 16) for objects to advertise that they permit cloning.
If a class implements Cloneable, Object’s clone method returns a field-by-field copy of the object; otherwise it throws CloneNotSupportedException.
In practice, a class that implements Cloneable is expected to provide a properly functioning public clone method.
In effect, the clone method functions as another constructor; you must ensure that it does no harm to the original object and that it properly establishes invariants on the clone.
The clone architecture is incompatible with normal use of final fields referring to mutable objects
Like a constructor, a clone method should not invoke any nonfinal methods on the clone under construction (Item 15).

A fine approach to object copying is to provide a copy constructor.A minor variant is to provide a static factory in place of a constructor.

Item 11: Consider implementing Comparable
compareTo method is declared in java.lang.Comparable interface.
By implementing Comparable, a class indicates that its instances have a natural ordering.
Float class’s compareTo method is inconsistent with equals

Leave a Comment

Effective Java – Part 1

This is the first part of the book summary based on Effective Java book by Joshua Bloch.

Chapter 1. Introduction

  • To use a language effectively, you need to master its grammar, vocabulary and usage.
  • How to make effective use of java and some of its libraries.
  • This book is not for beginners.
  • Fundamental Principles – Clarity, Simplicity, No Surprises, Reuse, Fail Fast.
  • Write programs that are clear, correct, usable, robust, flexible, and maintainable

Chapter 2. Creating and Destroying Objects

Item 1: Consider providing static factory methods instead of constructors
One advantage of static factory methods is that, unlike constructors, they have names. A class can have only a single constructor with a given signature. Static factory methods do not have this limitation. Providing two constructors whose parameter lists differ only in the order of their parameter types is a bad idea. 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.

The main disadvantage of static factory methods is that classes without public or protected constructors cannot be subclassed. A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.

valueOf returns an instance that has, loosely speaking, the same value as its parameters.
getInstances returns an instance that is described by its parameters but cannot be said to have the same value.

Item 2: Enforce the singleton property with a private constructor
Two approaches to implementing singletons are usinga a public static final field and using a static factory method.
To make a Singleton serializable, provide a readResolve method.

Item 3: Enforce noninstantiability with a private constructor
In the absence of explicit constructors in a class,the compiler provides a public, parameterless default constructor. Attempting to enforce noninstantiability by making a class abstract does not work. A class can be made noninstantiable by including a single explicit private constructor. This also prevents the class from being subclassed

Item 4: Avoid creating duplicate objects
An object can always be reused if it is immutable (Item 13). You can often avoid creating duplicate objects by using static factory methods (Item 1).
You can reuse mutable objects that you know will not be modified. An adapter is one object that delegates to a backing object, providing an alternative interface to the backing object.Because an adapter has no state beyond that of its backing object, there’s no need to create more than one instance of a given adapter to a given object.

Avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight.

Item 5: Eliminate obsolete object references
An obsolete reference is simply a reference that will never be dereferenced again. Null out references once they become obsolete or reuse the variable in which it was contained or to let it fall out of scope.
Whenever a class manages its own memory, the programmer should be alert for memory leaks.

Item 6: Avoid finalizers
Don’t use finalizers except as a safety net or to terminate noncritical native resources.Provide an explicit termination method instead. Nothing time-critical should ever be done by a finalizer. Never depend on a finalizer to update critical persistent state.

Explicit termination methods are often used in combination with the try-finally construct to ensure prompt termination.

Finalizers are unpredictable, often dangerous, and generally unnecessary. There is no guarantee that finalizers will be executed promptly or executed at all.

If an uncaught exception is thrown during finalization, the exception is ignored,and finalization of that object terminates

If a class (other than Object) has a finalizer and a subclass overrides it, the subclass finalizer must invoke the superclass finalizer manually.
If you need to associate a finalizer with a public, nonfinal class, consider using a finalizer guardian to ensure that the finalizer is executed, even if a subclass finalizer fails to invoke super.finalize

Leave a Comment

Hello WordPress

This is my first post.

Leave a Comment

Hello world!

Welcome to WordPress.com. This is your first post. Edit or delete it and start blogging!

Comments (1)