Sunday, April 19, 2015

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.

No comments: