Effective Java
Rate it:
Open Preview
Started reading December 26, 2020
8%
Flag icon
Item 7: Eliminate obsolete object references
8%
Flag icon
“memory leak,” which can silently manifest itself as reduced performance due to increased garbage collector activity or increased memory footprint.
8%
Flag icon
An obsolete reference is simply a reference that will never be dereferenced again.
8%
Flag icon
Memory leaks in garbage-collected languages (more properly known as unintentional object retentions) are insidious.
8%
Flag icon
null out references once they become obsolete.
8%
Flag icon
It is always beneficial to detect programming errors as quickly as possible.
8%
Flag icon
Nulling out object references should be the exception rather than the norm. The best way to eliminate an obsolete reference is to let the variable that contained the reference fall out of scope. This occurs naturally if you define each variable in the narrowest possible scope
8%
Flag icon
whenever a class manages its own memory, the programmer should be alert for memory leaks.
8%
Flag icon
Another common source of memory leaks is caches.
8%
Flag icon
If you’re lucky enough to implement a cache for which an entry is relevant exactly so long as there are references to its key outside of the cache, represent the cache as a WeakHashMap; entries will be removed automatically after they become obsolete.
8%
Flag icon
A third common source of memory leaks is listeners and other callbacks.
8%
Flag icon
One way to ensure that callbacks are garbage collected promptly is to store only weak references to them, for instance, by storing them only as keys in a WeakHashMap.
8%
Flag icon
debugging tool known as a heap profiler
8%
Flag icon
Item 8: Avoid finalizers and cleaners
8%
Flag icon
Finalizers are unpredictable, often dangerous, and generally unnecessary.
8%
Flag icon
As of Java 9, finalizers have been deprecated, but they are still being used by the Java libraries. The Java 9 replacement for finalizers is cleaners. Cleaners are less dangerous than finalizers, but still unpredictable, slow, and generally unnecessary.
9%
Flag icon
In Java, the garbage collector reclaims the storage associated with an object when it becomes unreachable, requiring no special effort on the part of the programmer.
9%
Flag icon
One shortcoming of finalizers and cleaners is that there is no guarantee they’ll be executed promptly
9%
Flag icon
never do anything time-critical in a finalizer or cleaner.
9%
Flag icon
For example, it is a grave error to depend on a finalizer or cleaner to close files because open file descriptors are a limited resource.
9%
Flag icon
never depend on a finalizer or cleaner to update persistent state.
9%
Flag icon
Another problem with finalizers is that an uncaught exception thrown during finalization is ignored, and finalization of that object terminates
9%
Flag icon
Normally, an uncaught exception will terminate the thread and print a stack trace, but not if it occurs in a finalizer—it won’t even print a warning.
9%
Flag icon
There is a severe performance penalty for using finalizers and cleaners.
9%
Flag icon
cleaners are much faster if you use them only as a safety net,
9%
Flag icon
Finalizers have a serious security problem: they open your class up to finalizer attacks.
9%
Flag icon
Throwing an exception from a constructor should be sufficient to prevent an object from coming into existence; in the presence of finalizers, it is not.
9%
Flag icon
To protect nonfinal classes from finalizer attacks, write a final finalize method that does nothing.
9%
Flag icon
Some Java library classes, such as FileInputStream, FileOutputStream, and ThreadPoolExecutor have finalizers that serve as safety nets.
9%
Flag icon
A native peer is a native (non-Java) object to which a normal object delegates via native methods.
10%
Flag icon
don’t use cleaners, or in releases prior to Java 9, finalizers, except as a safety net or to terminate noncritical native resources.
10%
Flag icon
Item 9: Prefer try-with-resources to try-finally
10%
Flag icon
try-finally - No longer the best way to close resources!
10%
Flag icon
If you write a class that represents a resource that must be closed, your class should implement AutoCloseable too.
10%
Flag icon
try-with-resources - the best way to close resources!
10%
Flag icon
Item 10: Obey the general contract when overriding equals
11%
Flag icon
So when is it appropriate to override equals? It is when a class has a notion of logical equality that differs from mere object identity and a superclass has not already overridden equals.
11%
Flag icon
A value class is simply a class that represents a value, such as Integer or String.
11%
Flag icon
Once you’ve violated the equals contract, you simply don’t know how other objects will behave when confronted with your object.
12%
Flag icon
The Liskov substitution principle says that any important property of a type should also hold for all its subtypes so that any method written for the type should work equally well on its subtypes
16%
Flag icon
override Object’s toString implementation in every instantiable class you write, unless a superclass has already done so. It makes classes much more pleasant to use and aids in debugging.
16%
Flag icon
Java supports covariant return types. In other words, an overriding method’s return type can be a subclass of the overridden method’s return type. This eliminates the need for casting in the client.
18%
Flag icon
Item 14: Consider implementing Comparable
20%
Flag icon
Item 15: Minimize the accessibility of classes and members
20%
Flag icon
The single most important factor that distinguishes a well-designed component from a poorly designed one is the degree to which the component hides its internal data and other implementation details from other components.
47%
Flag icon
In Java 8, functional interfaces, lambdas, and method references were added to make it easier to create function objects. The streams API was added in tandem with these language changes to provide library support for processing sequences of data elements.
48%
Flag icon
One line is ideal for a lambda, and three lines is a reasonable maximum. If you violate this rule, it can cause serious harm to the readability of your programs.
48%
Flag icon
The primary advantage of lambdas over anonymous classes is that they are more succinct.
70%
Flag icon
If you believe a condition is likely to allow for recovery, use a checked exception; if not, use a runtime exception. If it isn’t clear whether recovery is possible, you’re probably better off using an unchecked exception, for reasons discussed in Item 71.
71%
Flag icon
To summarize, throw checked exceptions for recoverable conditions and unchecked exceptions for programming errors. When in doubt, throw unchecked exceptions. Don’t define any throwables that are neither checked exceptions nor runtime exceptions. Provide methods on your checked exceptions to aid in recovery.