Effective Java 相关笔记

Item 1: Consider static factory methods instead of constructors

Advantages:

  • One advantage of static factory methods is that, unlike constructors, they have names.

  • A second advantage of static factory methods is that, unlike constructors, they are not required to create a new object each time they’re invoked.

  • A third advantage of static factory methods is that, unlike constructors, they can return an object of any subtype of their return type.(service provider framework)

  • A fourth advantage of static factory methods is that they reduce the ver- bosity of creating parameterized type instances.(type inference)

Disadvantages:

  • The main disadvantage of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.
  • A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.

Here are some common names for static factory methods:

  • valueOf—Returns an instance that has, loosely speaking, the same value as its parameters. Such static factories are effectively type-conversion methods.

  • of—A concise alternative to valueOf, popularized by EnumSet (Item 32).

  • getInstance—Returns an instance that is described by the parameters but cannot be said to have the same value. In the case of a singleton, getInstance takes no parameters and returns the sole instance.

  • newInstance—Like getInstance, except that newInstance guarantees that each instance returned is distinct from all others.

  • get_Type_—Like getInstance, but used when the factory method is in a differ- ent class. Type indicates the type of object returned by the factory method.

  • new_Type_—Like newInstance, but used when the factory method is in a differ- ent class. Type indicates the type of object returned by the factory method.

Item 2: Consider a builder when faced with many constructor parameters

In short, the telescoping constructor pattern works when the number of parameters is small, but it is hard to write client code when there are many parameters, and harder still to read it.

A second alternative when you are faced with many constructor parameters is the _JavaBeans _pattern, in which you call a parameterless constructor to create the object and then call setter methods to set each required parameter and each optional parameter of interest.

Unfortunately, the JavaBeans pattern has serious disadvantages of its own. Because construction is split across multiple calls, a JavaBean may be in an inconsistent state partway through its construction.

A related disadvantage is that the JavaBeans pattern pre- cludes the possibility of making a class immutable (Item 15), and requires added effort on the part of the programmer to ensure thread safety.

Luckily, there is a third alternative that combines the safety of the telescoping constructor pattern with the readability of the JavaBeans pattern. It is a form of the Builder pattern. The Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters, especially if most of those parameters are optional.

Item 3: Enforce the singleton property with a private constructor or an enum type

A single-element enum type is the best way to implement a singleton.

Item 4: Enforce noninstantiability with a private constructor

Such_ utility classes _like _java.util _were not designed to be instantiated: an instance would be nonsensical. A default construc- tor is generated only if a class contains no explicit constructors, so a class can be made noninstantiable by including a private constructor.

Item 5: Avoid creating unnecessary objects

An object can always be reused if it is immutable. You can often avoid creating unnecessary objects by using static factory methods in preference to constructors on immutable classes that provide both.

Because an adapter has no state beyond that of its backing object, there’s no need to create more than one instance of a given adapter to a given object.

The lesson is clear: prefer primitives to boxed primitives, and watch out for unintentional autoboxing.

Item 6: Eliminate obsolete object references

The best way to eliminate an obsolete reference is to let the variable that contained the reference fall out of scope. Generally speaking, whenever a class manages its own memory, the programmer should be alert for memory leaks. Whenever an element is freed, any object references contained in the element should be nulled out.

Because memory leaks typically do not manifest themselves as obvious failures, they may remain present in a system for years. They are typically discovered only as a result of careful code inspection or with the aid of a debugging tool known as a heap profiler. Therefore, it is very desirable to learn to anticipate problems like this before they occur and prevent them from happening.

Item 7: Avoid finalizers

One shortcoming of finalizers is that there is no guarantee they’ll be executed promptly. It can take arbitrarily long between the time that an object becomes unreachable and the time that its finalizer is executed. There is a severe performance penalty for using finalizers.

So what should you do instead of writing a finalizer for a class whose objects encapsulate resources that require termination, such as files or threads? Just provide an explicit termination method, and require clients of the class to invoke this method on each instance when it is no longer needed. Explicit termination methods are typically used in combination with try-finally construct to ensure termination.

Item 8: Obey the general contract when overriding equals

Sometimes you don’t need to override the equals method if any of the following conditions apply:

  • Each instance of the class is inherently unique.

  • You don’t care whether the class provides a “logical equality” test.

  • A superclass has already overridden equals, and the superclass behavior is appropriate for this class.

  • The class is private or package-private, and you are certain that its equals method will never be invoked.

When you override the equals method, you must adhere to its general contract. Here is the contract:

  • Reflexive: For any non-null reference value x, x.equals(x) must return true.

  • Symmetric: For any non-null reference values x and y, x.equals(y) must return true if and only if y.equals(x) returns true.

  • Transitive: For any non-null reference values x, y, z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) must return true.

  • Consistent: For any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.

  • For any non-null reference value x, x.equals(null) must return false.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值