For example, the Java programming language is object-oriented with single inheritance and supports an imperative (statement-oriented) coding style within each method. Likewise, there are dozens of books on the libraries and APIs associated with the Java programming language.
Preface to the Third Edition
Preface to the Second Edition
Preface to the First Edition
My focus on API design may seem a bit unnatural to enthusiasts of the new lightweight software development methodologies, such as Extreme Programming. I hope this book reflects my enthusiasm and allows you to use the language more effectively and enjoyably.
Acknowledgments for the Third Edition
Acknowledgments for the Second Edition
Acknowledgments for the First Edition
Consider static factory methods instead of constructors
The service access API is the flexible static factory that forms the basis of the service provider framework. A second shortcoming of static factory methods is that they are difficult for programmers to find.
Consider a builder when faced with many constructor parametersparameters
Then the client calls setter-like methods on the builder object to set each optional parameter of interest. The parameters of the builder can be adjusted between invocations of the build method to vary the objects that are created.
Enforce the singleton property with a private constructor or an enum type constructor or an enum type
An advantage of the static factory approach is that it gives you the flexibility to change your mind about whether the class is a singleton without changing its API. A second advantage is that you can write a generic singleton factory if your application requires it (item 30).
Enforce noninstantiability with a private constructor
Prefer dependency injection to hardwiring resources
The dependency injection pattern is so simple that many programmers use it for years without knowing it has a name. This mess is almost eliminated by using a dependency injection framework like Dagger [Dagger], Guice [Guice] or Spring [Spring].
Avoid creating unnecessary objects
If a class containing an enhanced version of the isRomanNumeral method is initialized but the method is never called, the ROMAN field will be initialized unnecessarily. Although creating multiple instances of the keySet view object is mostly harmless, it is unnecessary and has no benefit.
Eliminate obsolete object references
A memory pool consists of the elements of an array of elements (object reference cells, not the objects themselves). The scavenger cannot possibly know this; for the garbage collector, all object references in the element array are equally valid.
Avoid finalizers and cleaners
While there's no guarantee that the cleaner or finalizer will work immediately (or at all), it's better to release the resource late than never if the client fails to do so. In this case, it's simply the numJunkPiles field, which represents the amount of junk in the room.
Prefer try -with-resources to try - finally
- Use the == operator to check if the argument is a reference to this object
The performance of the equals method can be affected by the order in which the fields are compared. If you're simply testing fields for equality, it's not hard to enforce the equality contract.
Always override toString
The advantage of specifying a format is that it serves as a standard, unambiguous, human-readable representation of an object. The toString method should return a concise, useful description of the object in an aesthetically pleasing format.
Override clone judiciously
If the clone method simply returns super.clone(), the resulting Stack instance will have the appropriate value. In order for the clone method on Stack to work properly, it must copy the internals of the stack.
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 section of the compareTo contract, which is a strong suggestion rather than a true requirement, simply states that the equality test imposed by .
Minimize the accessibility of classes and members
You can expose constants via public static final fields, provided the constants form an integral part of the abstraction from the class. From Java 9, two more implicit access levels are introduced as part of the module system.
In public classes, use accessor methods, not public fields
In the case of a private nested class, the scope of the change is further limited to the enclosing class. Several classes in the Java platform libraries violate the advice that public classes should not expose fields directly.
Minimize mutability
Instead of making an immutable class final, you can make all its constructors private or package-private and add public static factories instead of the public constructors (point 1). You should only provide a public mutable companion class to your immutable class when you have confirmed that it is necessary for satisfactory performance (paragraph 67).
Favor composition over inheritance
Each instance method in the new class invokes the corresponding method on the containing instance of the existing class and returns the results. Inheritance is only appropriate in circumstances where the subclass is indeed a subtype of the superclass.
Design and document for inheritance or else prohibit it
Then replace each self-invocation of an overridable method with a direct call to the overridable method's private helper method. You must document all of its self-use patterns, and once you have documented them, you must commit to them for the life of the class.
Prefer interfaces to abstract classes
By convention, skeletal implementation classes are called AbstractInterface, where Interface is the name of the interface they implement. Whenever possible, you should provide the skeleton implementation via default methods on the interface so that all implementers of the interface can make use of it.
Design interfaces for posterity
The Apache version also provides the option to use a client-supplied object for the lock instead of a collection. Although default methods are now part of the Java platform, it is still very important to design interfaces carefully.
Use interfaces only to define types
Consider adding underscores to numeric literals, whether fixed or floating-point, if they contain five or more consecutive digits. 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 corresponding implementation of each abstract method in the root class. 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.
Favor static member classes over nonstatic
Common use of public class non-static member class MySet
Limit source files to a single top-level class
Thus, the program's behavior is affected by the order in which the source files are passed to the compiler, which is clearly unacceptable. The compiler automatically casts for you and tells you at compile time if you try to cast an object of the wrong type.
Don’t use raw types
Test.java:10: warning: [untagged] untagged call to add(E) as a member of raw type List. If you replace the raw type List with the parameterized type List
Eliminate unchecked warnings
If you find yourself using the SuppressWarnings annotation on a method or constructor that is more than one line long, you might want to move it to a local variable declaration. It is illegal to put a SuppressWarnings annotation on the return because it is not a statement [JLS, 9.7].
Prefer lists to arrays
List
Favor generic types
As explained in Item 28, you cannot create an array of a non-reverifiable type, such as E. Again, you can easily prove to yourself that the unchecked cast is safe, so it is appropriate to suppress the warning.
Favor generic methods
Using a recursive type bound to express mutual comparability public static
Use bounded wildcards to increase API flexibility
The wildcard type for a parameter that serves as a producer E public void pushAll(Iterable extends E> src). The wildcard type for the parameter that serves as a public T selector producer (Collection extends T> selections).
Combine generics and varargs judiciously
In Java 7, the SafeVarargs annotation was added to the platform to allow the author of a method with a generic varargs parameter to automatically suppress client warnings. Whenever the compiler warns you about possible heap pollution of a generic varargs parameter in a method you control, make sure the method is safe.
Consider typesafe heterogeneous containers
The next thing to notice is that the value type of favoritesMap is simple. It simply checks that its argument is an instance of the type represented by the class object.
Use enums instead of int constants
An enum type can start life as a simple collection of enum constants and evolve over time into an abstract abstraction. It is not necessary for the set of constants in an enum type to remain fixed forever.
Use instance fields instead of ordinals
Use EnumSet instead of bit fields
Here's what the previous example looks like when it's changed to use enums and enum sets instead of bit fields. The EnumSet class combines the precision and performance of bit fields with all the many advantages of enum types described in Section 34.
Use EnumMap instead of ordinal indexing
So, for example, if a garden contains annuals and perennials, but not biennials, the ByLifeCycle plant size will be three in the EnumMap version and two in both flow-based versions. The map type is Map
Emulate extensible enums with interfaces
You can define another enum type that implements this interface and use instances of this new type instead of the base type. For example, suppose you want to define an extension to the type of operation shown earlier, consisting of the exponentiation and remainder operations.