James Gosling, colleague and vice president of Sun Microsystems, Inc., and inventor of the Java programming language. Gilad Bracha, renowned engineer at Cadence Design Systems, and co-author of The Java™ Language Specification, Third Edition (Addison-Wesley, 2005).
Preface to the Second Edition
Preface to the First Edition
Even if you're not developing reusable components, thinking in these terms tends to improve the quality of the software you write. My focus on API design may seem a bit unnatural to followers of new lightweight software development methodologies such as Extreme Programming [Beck99].
Acknowledgments for the Second Edition
Acknowledgments for the First Edition
Consider static factory methods instead of constructors
A class can provide a public static factory method, which is simply a static method that returns an instance of the class. The service access API is the "flexible static factory" that forms the basis of the service provider framework.
Consider a builder when faced with many constructor parametersparameters
The client then calls the setter-like methods on the builder object to set each optional parameter it is interested in. Builder parameters can be changed during object creation to make the objects change.
Enforce the singleton property with a private constructor or an enum type constructor or an enum type
The main advantage of the public field approach is that the declarations make it clear that the class is a singleton: the public static field is final and will therefore always contain the same object reference. An advantage of the factory method approach is that it gives you the flexibility to change your mind about whether the class should be a singleton without changing the API.
Enforce noninstantiability with a private constructor
Avoid creating unnecessary objects
The TheisBabyBoomer method unnecessarily creates a new calendar, timezone, and two date instances each time it is called. While creating multiple instances of the keySet view object is harmless, it is also unnecessary.
Eliminate obsolete object references
The storage pool consists of the elements of the elements array (the object reference cells, not the objects themselves). The garbage collector has no way of knowing this; for the garbage collector, all the object references in the elements array are equally valid.
Avoid finalizers
- Use the == operator to check if the argument is a reference to this object
- Use the instanceof operator to check if the argument has the correct type
- When you are finished writing your equals method, ask yourself three questions: Is it symmetric? Is it transitive? Is it consistent? And don’t just
The performance of the equals method can be affected by the order in which fields are compared. If you're simply testing fields for equality, it's not hard to stick to the equals contract.
Always override hashCode when you override equals
By multiplying in step 2.b, the result depends on the order of the fields, which gives a much better hash function if the class has many similar fields. Don't be tempted to exclude important parts of the object from the hash code calculation to improve performance. This is generally not a good idea, as it severely limits your ability to improve the hash function in future releases.
Always override toString
The advantage of specifying the format is that it serves as a standard, unambiguous, human-readable representation of the object. The downside to specifying the format of the toString return value is that once you specify it, you're stuck with it for life, assuming your class is widely used. Whether or not you specify the format provides programmatic access to all the information contained in the value returned by toString.
Override clone judiciously
So if you override the clone method in a nonfinal class, you must return an object obtained by calling super.clone. Object's clone method is declared to throw CloneNotSupportedException, but overriding clone methods can omit this declaration. Object's clone method is not synchronized, so even if it is otherwise satisfactory, you may need to write a synchronized clone.
Consider implementing Comparable
If you want to add a value component to a class that implements Comparable, don't extend it; write an unrelated class that contains an instance of the first class. The final paragraph of the CompareTo contract, which is a strong suggestion rather than an actual provision, simply states that the equality test imposed by the. Also note that the parameter of the CompareTo method is a CaseInsensitive-String and not an object.
Minimize the accessibility of classes and members
But reducing the availability of a free public class is far more important than for a package-private top-level class: the public class is part of the package's API, while the package-private top-level class is already part of its implementation. Fortunately, that's not necessary either, since tests can be made to run as part of the package being tested, thus accessing its package-private elements. You can expose constants via public static final fields, provided the constants form an integral part of the abstraction from the class.
In public classes, use accessor methods, not public fields
This approach generates less visual clutter than the accessor method approach, both in the class definition and in the client code that uses it. In the case of a nested private class, the scope of the change is further limited to the enclosing class. Some classes in the Java platform libraries violate the advice that public classes should not expose fields directly.
Minimize mutability
The batch-private mutable companion class approach works well if you can predict exactly what complex multi-step operations clients will want to perform in your immutable class. Another way to make a final class immutable is to make all its constructors private or package private and to add public static factories instead of public constructors (point 1). Provide a public mutable companion class for your immutable class only after you confirm that it is necessary to achieve satisfactory performance (point 55).
Favor composition over inheritance
This design is called composition because the existing class becomes a component of the new one. Each instance method in the new class calls the corresponding method on the enclosing instance of the existing class and returns the results. Inheritance is only appropriate in circumstances where the subclass is actually a subtype of the superclass.
Design and document for inheritance or else prohibit it
In the case of the readObject method, the overriding method will run before the subclass state has been deserialized. In the case of the clone method, the overriding method will run before the subclass's clone method has a chance. Then replace each self-invocation of an overridable method with a direct call to the overridable method's private helper method.
Prefer interfaces to abstract classes
The interface still defines the type, but the skeleton implementation takes all the work out of the implementation. For most interface implementers, extending the skeleton implementation is an obvious choice, but it is strictly optional. If you export a non-trivial interface, you should strongly consider providing a skeleton implementation to accompany it.
Use interfaces only to define types
Typically, a helper class requires clients to qualify constant names with the class name, for example PhysicalConstants.AVOGADROS_NUMBER.
Prefer class hierarchies to tagged classes
Also include in each subclass the appropriate implementation of each abstract method in the main class. The code is simple and clear and contains none of the boilerplate text from the original. The compiler ensures that each class's constructor initializes its data fields, and that each class has an implementation for each abstract method declared in the root class.
Use function objects to represent strategies
In other words, we need to define a strategy interface to go with the concrete strategy class. Instead, a "host class" can export a public static field (or static factory method) whose type is the strategy interface, and the concrete strategy class can be a nested private host class. When a concrete strategy is designed for repeated use, it is generally implemented as a private static member class and exported to a final public static field whose type is the strategy interface.
Favor static member classes over nonstatic
Typical usage of a non-static member class public class MySet
Don’t use raw types in new code
Just what is the difference between the raw type List and the parameterized type List
Eliminate unchecked warnings
The SuppressWarnings annotation can be used at any level of granularity, from the declaration of a single local variable to the entire class. If you find yourself using the SuppressWarnings annotation on a method or constructor that is longer than one line, you may be able to move it to a local variable declaration. If you cannot resolve an unchecked warning, and you can prove that the code that raised it is type-safe, suppress the warning with the @SuppressWarnings("unchecked") annotation to the narrowest extent possible.
Prefer lists to arrays
List
Favor generic types
As explained in item 25, you cannot create an array of a non-returnable type, such as E. Again, you can easily prove to yourself that the unmarked cast is safe, so suppressing the warning is appropriate. The vast majority of generic types are like our Stack example in that their type parameters have no restrictions: you can create a Stack
Favor generic methods
Creating an instance of a parameterized type using Map
Use bounded wildcards to increase API flexibility
A wildcard type for a parameter that serves as a producer E static
Consider typesafe heterogeneous containers
The thing to note is that the wildcard type is nested: it is not the type of card that is a wildcard type, but the type of its key. The next thing you'll notice is that the value type of the favorites card is simple. It simply checks whether the argument is an instance of the type represented by the Class object.
Use enums instead of int constants
For example, suppose you are writing an enum type to represent the operations on a basic four-function calculator, and you want Implementation of a fromString method on a private static final Map of type enum
Use instance fields instead of ordinals
Use EnumSet instead of bit fields
Here's what the previous example looks like when modified to use enums instead of bit fields. 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 brevity and performance of bit fields with all the many benefits of enum types, described in Item 30.
Use EnumMap instead of ordinal indexing
Using an EnumMap to bind data to a Map enum
Emulate extensible enums with interfaces
While the enum type (BasicOperation) is not extensible, the interface type (Operation) is, and it is the interface type used to represent operations in APIs. You can define another enum type that implements this interface and use instances of that new type instead of the base type. These enums can then be used wherever the base enum type can be used, assuming the APIs are written in terms of an interface.
Prefer annotations to naming patterns
The declaration for the annotation type Test is itself annotated with the annotations Retention and Target. The four methods that are not annotated Test will be ignored by the testing tool. It is quite simple to modify the test execution tool to handle the new version of ExceptionTest.
Consistently use the Override annotation