Effective Java 78條軍規

Effective Java, 2nd Edition

by Joshua Bloch

I, Michael Parker, own this book and took these notes to further my own learning. If you enjoy these notes, please purchase the book!

Chapter 2: Creating and Destroying Objects創建和銷燬對象

Item 1: Consider static factories instead of constructors考慮使用靜態工廠方法代替構造器

  • An instance-controlled class is one that uses static factories to strictly control what instances exist at any time.
  • By convention, static factory methods for an interface named Type are put in a non-instantiable class named Types.
  • When naming static factory methods, getInstance may return the same instance, while newInstance should not.
  • 靜態工廠方法與構造器的第一大優勢在於:他們有名稱
  • 第二大優勢:不必在每次調用他們的時候都創建一個新的實例
  • 第3大優勢:他們可以返回任何原返回類型的任何子類型對象
  • 靜態工廠方法的主要缺點1:類如果不包含public或proctected的構造器,就不能被子類化
  • 靜態工廠方法的缺點2:他們與其他的靜態方法實質上沒有任何區別
  • 靜態工廠的慣用名稱:valuOf,of,getInstance,newInstance,getType,newType

Item 2: Consider a builder when faced with many constructor parameters遇到多個構造器參數時要考慮用構建器

  • The builder pattern simulates optional named parameters in Ada and Python.
  • A builder whose parameters have been set makes a fine abstract factory, assuming some generic Builder<T> interface.
  • 重疊構造器模式是可行的,但是當有很多參數的時候,客戶端代碼會很難編寫
  • Builder模式代碼易於閱讀,模擬了具名的可選參數
  • Class.newInstance破壞了編譯時的異常檢查
  • JavaBean模式會導致在構造過程中JavaBean可能處於不一致狀態

Item 3: Enforce the singleton property with a private constructor or an enum type用私有構造器或枚舉類型強化Singleton屬性

  • Adding implements Serializable to a singleton class is not enough, you must declare all fields transient and provide a readResolve method.
  • A single-element enum type provides the serialization for free and is the best way to implement a singleton.
  • 現代的jvm實現幾乎都能講靜態工廠方法的調用內聯化
  • 爲了維護並保證Singleton,必須聲明所有實例域都是transient的,並提供一個readResolve方法。否則每次反序列化一個實例時都會創建一個新的實例。
  • 單元素的枚舉類型已經成爲實現Singleton的最佳方法

Item 4: Enforce non-instantiability with a private constructor使用私有構造器強化不可實例化的能力

  • A private constructor not only supresses instantiation, but subclassing.
  • 例如工具類不希望被實例化,實例對它沒有任何意義
  • 企圖通過將類做成抽象類來強制該類不可被實例化,這是行不通的。該類可以被子類化,並且該子類可以被實例化。

Item 5: Avoid creating unnecessary objects避免創建不必要的對象

  • Often lazy initialization only complicates the implementation and yields no noticeable performance increase.
  • Prefer primitives to boxed primitives, as unintentional autoboxing can lead to creating many new instances.
  • Highly optimized garbage collectors can easily outperform object pools that do not contain heavyweight objects.
  • 一般來說,最好能重用對象而不是在每次需要的時候就創建一個相同功能的新對象。
  • 延遲初始化中常見的情況會使方法的實現變得複雜,從而無法將性能顯著地提高到超出已達到的水平。
  • 在Java1.5發行版中,有一種創建多餘對象的新方法,成爲自動封箱。
  • 要優先使用基本類型而不是裝箱基本類型,當心無意識的自動封箱。

Item 6: Eliminate obsolete object references消除過期對象的引用

  • Whenever a class manages its own memory, like a stack or object pool, the programmer should be alert for memory leaks.
  • Caches, listeners, and callbacks can all be sources of memory leaks, but weak references can help.
  • 所謂過期引用,是指永遠也不會再被刪除的引用
  • 如果一個對象引用被無意識地保留起來了,那麼,垃圾回收機制不僅不會處理這個對象,而且不會處理被這個對象所引用的所有其他對象。
  • 清空對象引用應該是一種例外,而不是一種規範行爲。消除過期引用的最好方法就是讓包含該引用的變量結束其生命週期。
  • 一般而言,只要類是自己管理內存,程序員就應該警惕內存泄露問題。
  • 內存泄露的另一個常見來源是緩存。可以用WeakHashMap代表緩存,當緩存中的項過期後,他們就會被自動刪除。
  • 緩存應該時不時地清除掉沒用的項,這項清除工作可以由一個後臺線程(可能是Timer或ScheduledThreadPoolExecutor)來完成。
  • 內存泄露的第3個常見來源是監聽器和其他回調。確保回調被當做垃圾回收的最佳方法時只保存他們的弱引用(weak reference),例如,只將他們保存成WeakHashMap中的鍵。

Item 7: Avoid finalizers避免使用finalize

  • Do not think of finalizers as Java's analogue of C++ destructors -- there's no guarantee finalizers will be called at all!
  • If an uncaught exception is thrown in a finalizer, it is ignored, and the finalization abruptly terminates.
  • There is a severe performance penalty for using finalizers -- object creation and deletion increases from nanoseconds to microseconds.
  • Java語言規範並不保證哪個線程將會執行finalize方法,所以除了不使用finalize方法之外,並沒有很輕便的方法能避免這樣的問題。
  • Java語言規範不僅不能保證finalize方法被及時地執行,而且根本就不保證它們會被執行。結論:不應該依賴finalize方法來更新重要的持久狀態。
  • 不要被System.gc和System.runFinalization這兩個方法所誘惑,它們確實增加了終結方法被執行的機會,但是它們並不保證終結方法就一定會被執行。
  • 使用終結方法有一個非常嚴重的性能損失。用終結方法後創建和銷燬對象慢了約430倍。
  • 怎樣做才能不用編寫finalize方法呢?只需要提供一個顯示的終止方法,並要求該類的客戶端在每個實例不再可用的時候調用這個方法。顯示的終止方法通常與try-finally結構結合起來使用,以確保及時終止。
  • 如果子類實現者覆蓋了超類的finalize方法(或者有意選擇不調用超類的finalize方法),那麼超類的finalize方法將永遠也不會被調用到。要防範這樣粗心大意或者惡意的子類是有可能的,代價就是爲每個將被finalize的對象創建一個附加的對象。不是把finalize方法放在要求終結處理的類中,而是把finalize方法放在一個匿名類中,該匿名類的唯一用途就是終結它的外圍實例(enclosing instance)。

Chapter 3: Methods Common to All Objects對於所有對象都通用的方法

Item 8: Obey the general contract when overriding equals覆蓋equals時請遵循通用約定

  • Override equals when a class has a notion of logical equality that differs from mere object identity, and the superclass has not provided a suitable implementation.
  • For classes that represent a value, such as Integer or Date, the equals method should always be overridden.
  • There is no way to extend an instantiable class and add a value component (field) while preserving the equals contract.
  • By using composition with views to internal components, you can add value components to instantiable classes without violating the equals contract.
  • To compare float and double values, use the Float.compare and Double.compare methods to deal with NaN and -0.0 values.
  • For best performance, first compare fields that are more likely to differ, or less expensive to compare.
  • 覆蓋equals時要遵循的通用約定:
  • 1-類的每個實例本質上都是唯一的。
  • 2-不關心是否提供了‘邏輯相等logical equality’的測試功能
  • 3-超類已經覆蓋了equals,從超類繼承過來的行爲對於子類也是合適的。
  • 4-類是private的或是包級私有的,可以確定它的equals永遠不會被調用。
  • equals等價關係約定
  • 自反性reflexive.x.equals(x)必須返回true
  • 對稱性symmetric,當且僅當y.equals(x)返回true時,x.equals(y)必須返回true
  • 傳遞性transive,如果x.equals(y)返回true,並且y.equals(z)返回true,那麼x.quals(z)也必須返回true.
  • 一致性consistent,多次調用x.equals(y)都會一致地返回true或一致地返回false.
  • 里氏交換原則認爲,一個類型的任何重要屬性也將適用於它的子類型,因此爲該類型編寫的任何方法,在它的子類型上也應該運行得很好。
  • Timestamp類有一個免責聲明,告誡程序員不要混用Date和Timestamp對象。
  • 實現高質量equals方法的訣竅:
  • 1-使用==操作符檢查‘參數是否爲這個對象的引用’
  • 2-使用instanceof檢查'參數是否爲正確的類型'
  • 3-把參數轉換爲正確的類型。因爲轉換之前已經做過instanceof測試,所以確保成功
  • 4-對於該類中的每個'關鍵significant'域,檢查參數中的域是否與該對象中相應的域相匹配。
  • 5-當你編寫完equals方法後,應該問下自己:它是否是對稱的,傳遞的,一致的?
  • 覆蓋equals方法時總要覆蓋hashCode方法

Item 9: Always override hashCode when you override equals重寫hashCode方法時記得重寫equals方法

  • To take the hash code of float and double values, use Float.floatToIntBits and Double.doubleToLongBits, respectively.
  • Immutability offers the chance to cache hash codes if computing them is expensive.
  • Try not to specify the behavior of your hash code method in Javadoc, as that limits your options for improving it later.
  • 在每個覆蓋了equals方法的類中,也必須覆蓋hashCode方法
  • 如果兩個對象根據equals方法比較是相等的,那麼兩個對象的hashCode方法必須產生相等的整數結果。相等的對象必須具有相等的散列碼。
  • 一個好的散列函數通常傾向於'爲不相等的對象產生不相等的散列碼'。
  • 在散列碼的計算過程中,可以把冗餘域redundant field排除在外。
  • 習慣上都使用素數來計算散列結果。31有個很好的特性,即用移位和減法來代替乘法,可以得到更好的性能:31*i==(i << 5)-i。
  • 不要試圖從散列碼計算中排除掉一個對象的關鍵部分來提高性能。

Item 10: Always override toString始終要覆蓋toString

  • If you specify the format in Javadoc, provide a static factory method accepting a String parameter so a client can convert between the two forms.
  • Provide programmatic information to all the information provided by toString, or clients may try to parse the string to retrieve it.
  • 在實際應用中,toString方法應該返回對象中包含的所有值得關注的信息
  • 實現toString時,在文檔中指定返回值的格式。
  • 無論你是否指定格式,都應該在文檔中明確地表明你的意圖。
  • 無論是否指定格式,都爲toString返回值中包含的所有信息,提供一種編程式的訪問途徑。

Item 12: Consider implementing Comparable考慮實現Comparable接口

  • Like the equals method, there is no way to extend and instantiable class with a new value component while preserving the compareTo contract.
  • If compareTo is consistent with equals, note that sorted collections (e.g. TreeSetTreeMap) use the equality test imposed by compareTo instead of equals and may break the interface (e.g. SetMap) contract.
  • Use methods Double.compare and Float.compare instead of relational operators, which don't obey the compareTo contract for floating point values.

Chapter 4: Classes and Interfaces類和接口

Item 13: Minimize the accessibility of classes and members使類和成員的可訪問性最小化

  • Private and package-private members can "leak" into the exported API if the class implements Serializable.
  • Even a protected member is part of the class's exported API and must be supported forever.
  • With the exception of public static final fields to immutable objects, public classes should have no public fields.

Item 14: In public classes, use accessor methods, not public fields在public類中使用public方法而非public屬性

  • If a class is package-private or a private nested class, there's nothing wrong with exposing its data.
  • A public class with immutable public fields is okay because it can enforce their invariants upon construction.

Item 15: Minimize mutability使可變性最小化

  • For immutable classes, the Java memory model requires that all fields be final to ensure correct behavior when passing an instance between threads without synchronization.
  • Defend against "leaking" references by making defensive copies in constructors, accessors, and readResolve methods when needed.
  • Instances of an immutable class can share internal objects with one another for efficiency.
  • If a client requires performing expensive multi-stage operations on your class, expose them as primitive methods, or provide a mutable companion class (like StringBuilder for String).

Item 16: Favor composition over inheritance複合優先於繼承

  • Inheritance violates encapsulation because the subclass depends on the implementation details of the superclass for its proper function.
  • Inheritance means you inherit the scope and flaws of an API, whereas composition allows you to design a better suited one.
  • If an appropriate interface exists, using composition and forwarding allows you to instrument any implementation of the interface, instead of a single implementation through inheritance.

Item 17: Design and document for inheritance, or else prohibit it要麼爲繼承設計和提供文檔,要麼禁止繼承

  • The class that allows subclassing must document its self-use of overridable methods.
  • The only way to test if a class is suitably designed for inheritance (e.g. provides all the necessary implementation hooks through protected methods) is to actually write subclasses.
  • Eliminating a class's self use of methods, typically through introducing private helper methods, can make a class safe to subclass.

Item 18: Prefer interfaces to abstract classes接口優先於抽象類

  • Use interfaces to allow construction of non-hierarchical type frameworks.
  • Simulated multiple inheritance is where a class implementing an interface can forward invocations to an instance of a private inner class that extends the skeletal implementation of that interface and hence does the bulk of the work.
  • A variant of a skeletal implementation is the simple implementation, which is a concrete class that defines the simplest possible implementation, such as AbstractMap.SimpleEntry.
  • Java只允許單繼承,所以,抽象類作爲類型定義受到了極大的限制。
  • 接口是定義mixin混合類型的理想選擇。
  • 接口允許我們構造非層次結構的類型框架。
  • 通過包裝器wrapper class模式,接口使得安全地增強類的功能成爲可能。通過對你導出的每個重要接口都提供一個抽象的骨架實現skelect implementation類,把接口和抽象類的優點結合起來。接口的作用仍然是定義類型,但是骨架實現類接管了所有與接口實現相關的工作。
  • 通過接口來定義允許多個實現的類型,與使用接口相比有一個明顯的優勢:抽象類的演變要比接口演變要容易得多。
  • 設計公有的接口要十分謹慎。接口一旦被公開發行,並且已被廣泛實現,再想改變這個接口幾乎是不可能的。

Item 19: Use interfaces only to define types接口只用於定義類型

  • Don't use constant interfaces, or interfaces that define no methods but only constants, which classes implement to access the constants without fully qualifying their names.
  • If the constants are static members of a class, and you really don't want to qualify their names, use the static import facility for brevity.

Item 21: Use function objects to represent strategies用函數對象表示策略

  • Classes that implement concrete strategies, or simulate function pointers, should be stateless and made into singletons.
  • When defining a strategy as an anonymous class that is inline in a method invocation, consider extracting the object as a private static final field so a new instance is not created upon every call.

Item 22: Favor static member classes over nonstatic優先考慮靜態成員類

  • Nonstatic member classes are ideal for providing adapters, or views of an outer class as an instance of some unrelated class.
  • An anonymous class have enclosing instances if and only if they occur in a non-static context.

Chapter 5: Generics

Item 23: Don't use raw types in new code

  • List<E> is read as "list of E", and List<String> is read as "list of string", where String is the actual type parameter and E is the formal type parameter.
  • While an instance of the raw type List could be designated to hold only types of a single class but opts out of type-checking, List<Object> is typesafe because it explicitly states that it can contain objects of any type.
  • The unbound wildcard type, such as in List<?>, represents a list of some unknown type and so forbids inserting any element other than null, unlike the raw type List which is not typesafe.

Item 24: Eliminate unchecked warnings

  • Always use the @SuppressWarnings annotation on the smallest scope possible, to not mask other, critical warnings.

Item 25: Prefer lists to arrays

  • Arrays are covariant, so Sub[] is a subtype of Super[], and reified, so they retain their type-information at runtime and Super[] can throw an ArrayStoreException when given a different subclass; by contrast, List<E> is covariant and erased.
  • Consequently, arrays provide runtime safety but not compile-time safety, while a generic type like List<E> provides compile-time safety but not runtime safety.

Item 27: Favor generic methods

  • You can exploit the type inference provided by generic methods and write generic static factory methods that make instances easier to create.
  • If you have an immutable, singleton instance of a generic class that could be shared across all types, make it private and of type Object, and then let a generic singleton factory method cast it to the caller's desired type.
  • The type bound <T extends Comparable<T>> may be read as "for every type T that can be compared to itself" and is the definition of a mutually comparable type.

Item 28: Use bounded wildcards to improve API flexibility

  • If a parameterized type represents a T producer, use <? extends T>; if a parameterized type represents a T consumer, use <? super T>.
  • Do not use wildcard types as return types, or clients will be forced to use wildcard types in their code.
  • Comparables and comparators are always consumers, so you should always use Comparator<? super T> in preference to Comparator<T>.
  • If a type parameter appears only once in a method declaration, replace it with a wildcard, using a private helper method to capture the type if necessary.

Item 29: Consider typesafe heterogeneous containers優先考慮類型安全的異構容器

  • A type token is a class literal is passed among methods to communicate both compile-time and runtime type information.
  • The cast method of the Class type is the dynamic analog of Java's cast operator, throwing a ClassCastException if the operation fails.
  • The "checked" collection wrappers in java.util.Collections use this method with type tokens to enforce, at runtime, that invalid types are not added to a collection through its raw type.

Chapter 6: Enums and Annotations枚舉和註解

Item 30: Use enum instead of int constants使用枚舉代替int常量

  • You can add or reorder constants in an enum type without recompiling its clients because the constant values are not compiled into the clients as they are with the int enum pattern.
  • Enums are by their nature immutable, and so all their fields should be final.
  • If you override the toString method of an enum type, consider writing a fromString method, similar to how the static valueOf method would perform if you had not overridden toString.
  • To share a constant specific method implementations between enum values, move each implementation into a private nested enum, and pass an instance of this strategy enum to the constructor of the top-level enum.

Item 32: Use EnumSet instead of bit fields使用EnumSet代替位域

  • An EnumSet is represented by one or more long values, and so many of its operations are effiiciently performed with bitwise arithmetic.

Item 33: Use EnumMap instead of ordinal indexing用EnumMap代替序數索引

  • When you access an array that is indexed by the ordinal value of an enum, it is your responsibility to use the correct int value, as no type safety is afforded.
  • An EnumMap contains an array internally, offering the speed of an ordinal-indexed array with the type safety and richness of the Map interface.
  • Instead of using an array of arrays to define a mapping from two enum values, use EnumMap<..., EnumMap<...>>, which is internally represented as an array of arrays.

Item 34: Emulate extensible enumerated types with interfaces用接口模擬可伸縮的枚舉

  • If two enumerated types implement the same interface, both their classes adhere to the type <T extends Enum<T> & InterfaceName>.
  • Since implementations cannot be inherited from one enum type to another, the functionality must be encapsulated in a helper class or a static helper method.

Item 35: Prefer annotations to naming patterns註解優先於命名模式

  • Annotations like Retention and Target for annotation type declarations are called meta-annotations.
  • A marker annotation is one with no parameter and simply serves to mark some class, method, or field for interpretation by some other method or program.

Item 36: Consistently use the Override annotation堅持使用override註解

  • There is no need to use the @Override annotation when a concrete class overrides an abstract method, i.e. implements it, because a differing signature will be caught by the compiler anyway.
  • In an abstract class or interface, annotate all methods you believe to override superclass or superinterface methods, whether concrete or abstract, to ensure that you don't accidentally introduce any new methods.

Item 37: Use marker interfaces to define types使用標記接口定義類型

  • Use a marker interface instead of an annotation if you want to write one or more methods that accept only objects that have this marking, or implement the interface.
  • Use a marker interface instead of an annotation if you want to limit the use of the marker to elements of a particular interface, by having the marker interface extend that interface.
  • A marker annotation, however, allows marking elements other than classes and interfaces, and allows adding more information while retaining backwards compatibility through type elements with defaults.

Chapter 7: Methods方法

Item 38: Check parameters for validity檢查參數有效性

  • Nonpublic methods should check their parameters using assertions, which are enabled with the -enableassertions command line flag, instead of explicitly throwing exceptions.
  • Skip checking a method's parameters before performing the computation if the validity check would be expensive or impractical and the validity check is performed implicitly during the computation.

Item 39: Make defensive copies when needed必要時進行保護性拷貝

  • When making defensive copies of constructor parameters, check the validity of the copies instead of the originals to guard against malicious changes to the parameters by another thread.
  • Do not use the clone method to make a defensive copy of a constructor parameter whose type is subclassable by untrusted parties.
  • The defensive copy can be replaced by documented transfer of ownership if copying the object would be costly and the class trusts its clients not to modify the components inappropriately.

Item 40: Design method signatures carefully謹慎設計方法簽名

  • If you go over four parameters, try to break up the method into orthogonal methods with fewer parameters, introduce helper classes that bundle related parameters together, or use a builder pattern.
  • Prefer two-element enum types to boolean parameters.

Item 41: Use overloading judiciously慎用重載

  • Beware that selection among overloaded methods is static, while selection among overridden methods is dynamic.
  • Avoid cases where the same set of parameters can be passed to different overloadings of a method by the addition of casts.
  • If a method with a primitive parameter overloads a method with a generic parameter, the two can become conflated from autoboxing.

Item 42: Use varargs judiciously慎用可變參數

  • Don't blindly retrofit every method that has a final array parameter to use varargs; use varargs only when a call operates on a variable-length sequence of values.

Item 43: Return empty arrays or collections, not nulls返回零長度的數組或集合而不是null

  • Returning null from an array or collection-valued method complicates the caller logic, and usually the callee's.
  • To eliminate the overhead from creating an empty collection or array, return the immutable empty collections in java.util.Collections, or create a static empty array which is necessarily immutable.

Item 44: Write doc comments for all exposed API elements爲所有導出的API元素編寫文檔註釋

  • To include a multiline code example in a doc comment, use a Javadoc {@code} tag wrapped inside an HTML <pre> tag.
  • The {@literal} tag is like the {@code} tag in that it eliminates the need to escape HTML metacharacters, but doesn't render the contents in monospaced font.
  • No two members or constructors should have the same summary description, which is the first (sometimes incomplete) sentence of a doc comment.

Chapter 8: General Programming通用程序設計

Item 45: Minimize the scope of local variables將局部變量的作用域最小化

  • Declare a variable at the latest point possible, typically right before it is first used, and strive to provide an initializer.
  • If the bound for a loop variable is expensive to compute on every iteration, store it in a loop variable that will fall out of scope with the counter variable.

Item 46: Prefer for-each loops to traditional for loops for-each循環優先於傳統for循環

  • If you are writing a type that represents a group of elements, have it implement the Iterable interface even if it does not implement Collection.
  • The enhanced for loop cannot be used if you need to remove elements through an iterator, reassign elements through a list iterator, or iterate over collections in parallel.

Item 47: Know and use the libraries瞭解和使用類庫

  • Every programmer should be familiar with the contents of java.lang and java.util (particularly the collections framework), and to a lesser extent java.io and java.util.concurrent.

Item 48: Avoid float and double if exact answers are required需要精確的結果時避免使用float和double

  • The BigDecimal can contain decimal values of arbitrary size and provides eight rounding modes, which is ideal for business calculations with legally mandated rounding behavior.
  • If you choose to keep track of the decimal point yourself, int provides up to nine decimal digits, while long provides up to eighteen.

Item 49: Prefer primitive types to boxed primitives基本類型優先於裝箱類型

  • Never use == on two boxed primitives, because this always performs identity comparison, while the < and > operators compare the underlying primitive values.
  • When you mix primitives and boxed primitives in a single operation, the boxed primitive is auto-unboxed, which can result in NullPointerExceptions.
  • Beware of boxed primitives being implicitly unboxed and then re-boxed, which can cause performance problems.

Item 50: Avoid strings where other types are appropriate如果其他類型更適合,避免使用String

  • Instead of using a key to represent an aggregate type, write a private static member class -- even if it only has two fields.

Item 51: Beware the performance of string concatenation當心字符串連接的性能

  • A consequence of strings being immutable is that the time to concatenate n strings is quadratic in n.
  • An alternative to using a StringBuilder is to try processing the strings one at a time to avoid all concatenation.

Item 52: Refer to objects by their interfaces通過接口引用對象

  • If you depend on any properties of an implementation not specified by its interface, such as its synchronization policy, use the class as a type and document the requirements.

Item 53: Prefer interfaces to reflection接口優先於反射機制

  • If a class is unavailable at compile time but there exists an appropriate interface, create instances reflectively and access them normally through their interface.
  • If writing a package that runs against multiple versions of some other package, you can compile it against the minimal environment required to support it, and access any newer classes or methods reflectively.

Item 55: Optimize judiciously謹慎地進行優化

  • Strive for encapsulation so that a part of the system can be rewritten for performance without changing its other parts.
  • You need to measure attempted optimization carefully on the Java platform, because the language does not have a strong performance model, or well-defined relative costs.

Item 56: Adhere to generally accepted naming conventions遵守普遍接受的命名慣例

  • Components of a package name should be short, generally eight or fewer characters, where abbreviations are encouraged and acronyms are acceptable.
  • Names of static final fields whose values are immutable should be in uppercase with words separated by underscores.
  • Methods that convert a type have the format toType, while methods that return a view have the format asType, and methods that return a primitive representation have the format typeValue.

Chapter 9: Exceptions異常

Item 57: Use exceptions for exceptional conditions僅在異常情況下才使用Exception

  • Do not force clients to use exceptions for ordinary control flow, and instead offer methods to test whether an exception could be thrown, such as hasNext for class Iterator.
  • Use a distinguished return value, like null, if the object is accessed by multiple threads or if the state-testing method duplicates the work of the state-dependent method.

Item 58: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors對可恢復的情況使用受檢異常,對編程性錯誤使用運行時異常

  • Use runtime exceptions to indicate programming errors, typically precondition violations.
  • Don't implement any new Error subclasses, and don't define a throwable that does not subclass Exception or RuntimeException.

Item 59: Avoid unnecessary use of checked exceptions避免不必要地使用受檢異常

  • When designing an API, only throw a checked exception if it can be prevented by a proper use of the API, and the programmer can take some useful action once thrown.

Item 60: Favor the use of standard exceptions優先使用標準異常

  • Throw a NullPointerException instead of an IllegalArgumentException if a caller passes in a null parameter where prohibited.
  • Throw an IndexOutOfBoundsException instead of an IllegalArgumentException if the caller passes in an invalid index for a sequence.

Item 61: Throw exceptions appropriate to the abstraction拋出與抽象對應的異常

  • Use exception translation, where low-level exceptions are caught and exceptions appropriate to the higher-level abstraction are thrown.
  • If an exception does not have a chaining-aware constructor, use the initCause method of Throwable.
  • Try to avoid low-level exceptions by checking the higher-level method's parameters upfront.

Item 62: Document all exceptions thrown by each method每個拋出的異常都要有文檔註釋

  • Document the unchecked exceptions a method can throw, thereby documenting its preconditions.
  • Do not use the throws keyword to include unchecked exceptions in a method declaration.

Item 63: Include failure-capture information in detail messages在消息細節中包含能捕獲的失敗信息

  • The toString method, or "detail message," should contain the values of all the parameters and fields contributing to the exception.
  • To capture this information easily, make them parameters to the constructor, and internally generate the detail message from them.

Item 64: Strive for failure atomicity努力使失敗保持原子性

  • A failed method invocation should leave the object in the state it was prior to the invocation.
  • Typically you can easily achieve failure atomicity by checking the parameters' validity before the operation.

Chapter 10: Concurrency併發

Item 66: Synchronize access to shared mutable data synchronize共享的可變數據

  • Synchronization is not just for mutual exclusion, but ensuring that a value written by one thread is seen by another.
  • Both read and write operations on mutable data must be synchronized or visibility is not guaranteed.
  • Beware that the increment and decrement operators are not atomic on volatile integers.

Item 67: Avoid excessive synchronization避免過度同步

  • Inside a synchronized region, do not invoke a method that is provided by the client as a function object, or can be overriden.
  • Reentrant locks simplify the construction of multi-threaded object oriented programs, but can allow foreign methods to access an object in an inconsistent state.
  • Only make a mutable class thread-safe if intended for concurrent use and you can achieve better concurrency with internal locking; otherwise, punt locking to the client.
發佈了58 篇原創文章 · 獲贊 4 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章