Chapter02. Creating and Destroying Objects

aim: when and how to create, when and how to avoid creating, how to ensure they are destroyed in a timely manner, how to manage any cleanup actions that must precede their destruction.

Item1. Consider static factory methods instead of constructors


A class can provide its client with static factory methods instead of public constructors.

public Boolean valueOf(boolean b){

        return b ? Boolean.TRUE : Boolean.False;

}

Advantages:

Unlike constructors, they have names.

         A static well-chosen method name is easier to use and the resulting client code easier to read; 

        A class can have only a single Constructor with a given signature, a static factory can return multi different objects with well-chosen method name(to highlight differences) and same method signature.

    Unlike constructors, they are not required to create a new object each time they're invoked.

This allows immutable classes to use preconstructed instances or to cache instances as they're constructed, and avoid creating unnecessary duplicate objects(similar to FlyWeight pattern);

        The ability to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time.【This classes are said to be instance-controlled】【reasons: singleton, noninstantiable, no two equal instances exist-a.equals(b) if and only if a==b】

    Unlike constructors, they can return an object of any subtype of their return type.

        Interface-based frameworks. Hiding implementation classed in this fashion leads to a very compact API.

        [Type 待写]

The class of returned object can vary from call to call as a function of the input parameters.

        Any subtype of the declared return type is permissible. The class of the returned object can vary from release to release.

        EnumSet, no public constructor only static factories. In OpenJDK, they return an instance of one of two subclasses, depending on the size of the underlying enum type: 64 or fewer elements, return a RegularEnumSet instance, backed by a single long(64 bit); 65 or more elements, return a JumboEnumSet instance, backed by a long array. The existence of these two implementation is invisible to clients. So a future release could add a third or fourth implementation of EnumSet if it proved beneficial for performance. Clients neither know nor care about the class of the object they get back from the factory, they care only that it is some subclass of EnumSet. 

The class of the returned object need not exist when the class containing the method is written.

SPI code example

Such flexible static factory method form the basis of service provider frameworks【SPI, like java Database Connectivity API, JDBC】, A service provider framework is a system in which multi service providers implement a service, and the system makes the implementation available to clients, decoupling the clients from the implementation.

There are 3 essential components in a service provider framework: service interface, which represents an implementation【Connection】;provider registration API, which providers use to register implementations【DriverManager.registerDriver】;service access API, which clients use to obtain instances of the service【DriverManager.getConnection】. The service access API is the flexible static factory that forms the basis of the service provider framework.

An optional forth component of a service provider framework is aservice provider interface, which describes a factory object that produce instances of the service interface【Driver】.

Bridge pattern【service access API return a richer service interface to clients than the one furnished by providers.】;Dependency injectionframeworks can be viewed as powerful service providers.

Since Java 6, the platform includes a general-purpose service provider framework, java.util.ServiceLoader, so you needn't and shouldn't write your own.【JDBC not use ServiceLoader, as the former predates the latter】.

Disadvantage

Providing only static factory methods without public or protected constructors cannot be subclassed.

They are hard for programmers to find.

Common names for static factory methods:

from--- type-conversion method: Date d = Date.from(instant);

of--- aggregation method: Set faceCards = EnumSet.of(JACK, QUEEN, KING);

valueOf---  BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);

instance or getInstance--- StackWalker luke = StackWalker.getInstace(options);

create or newInstance--- guarantee each call returns a new instance,

            Object newArray = Array.newInstance(classObject, arrayLen);

getType--- factory method is in a different class.

            FileStore fs = Files.getFileStore(Path);

newType--- factory method is in a different class.

            BufferedReader br = Files.newBufferedReader(path);

type--- concise alternative to getType and newType.

            List<Complaint> litany = Collections.list(legacyLitany);

Summary

    Avoid the reflex to provide public constructors without first considering static factories.


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


telescoping constructor pattern: provider a constructor with only the required parameters, another with a single optional parameter, a third with two optional parameters, and so on.

The telescoping constructor pattern works, but it is hard to write client code when there are many parameters, and harder still to read it.

JavaBeans pattern, call a parameterless constructor to create the object and then call setter methods to set each required parameter.

A JavaBean may be in an inconsistent state partway through its construction【每次set都改变object的状态】. And the JavaBeans pattern precludes the possibility of making a class immutable.

Builder pattern. Client calls a constructor(or static factory) with all of the required parameters and gets a builder object, then client calls setter-like methods on the builder object to set each optional parameter, finally client falls a parameterless build method to generate the object, which is typically immutable.

Builder code example

The Builder pattern simulates named optional parameters.

The Builder pattern is well suited to class hierarchies.

Builder hierarchy code example

generic type with a recursive type parameter.[待]

simulated self-type idiom.【待】

covariant return typing: A subclass method is declared to return a subtype of the return type declared in the superclass.

advantage

    Builders can have multi varargs parameters because each parameter is specified in its own method.

    A single builder can be used repeatedly to build multi objects.

disadvantage

    In order to create object, you must first create its builder, could be a problem in performance-critical situations.

    Builder pattern is verbose, so it should be used only if there are enough parameters.(>=4)

Summary

    The Builder pattern is a good choice when designing classes whose constructors or static factories would have more than a handful of parameters.


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


A singleton is simply a class that is instantiated exactly once. Making a class a singleton can make it difficult to test its client.

There are three ways to implement singletons.

public class Elvis{

    public static final Elvis INSTANCE = new Elvis();

    private Elvis(){}

    private Object readResolve(){

        return INSTANCE;

    }

}

 public class Elvis{

    private final static Elvis INSTANCE = new Elvis();

    private Elvis(){}

    public static Elvis getInstance(){

        return INSTANCE;

    }

    private Object readResolve(){       

        return INSTANCE;   

    }

}

public enum Elvis{

    INSTANCE;

}

To make a singleton class (approach 1, 2) serializable, it is not sufficient to add implements Serializable to its declaration. Need declare all instance fields transient and provide a readResolve method, otherwise each time a serialized instance is deserialized, a new instance will be created.

serialization code example

Summary

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

Item 4: Enforce noninstantiability with a private constructor

Attempting to enforce noninstantiability by making a class abstract does not work, because the class can be subclassed(the subclass instantiated) and mislead user into thinking the class was designed for inheritance.

A class can be made noninstantiable by including a private constructor.

// Noninstantiable utility class

public class UtilityClass{

    // Suppress default constructor for noninstantiablity

    private UtilityClass(){

        throw new AssertionError();

    }

}

As a side effect, this prevent the class from being subclassed.[all constructors must invoke a superclass constructor, explicitly or implicitly]


Item 5: Prefer dependency injection to hardwiring resources


Static utility classes and singletons are inappropriate for classes whose behavior is parameterized by an underlying resource.

Dependency injection: pass the resource into the constructor when creating a new instance.

Dependency injection preserves immutability, so multiple clients can share dependent objects.

代码【待】


Item 6: Avoid creating unnecessary objects


Don't create a new object when you should reuse an existing one.

Prefer Pattern.matcher.matches to Sting.matches because former can cache Pattern when loop multi times.

Autoboxing blurs but does not erase the distinction between primitive and boxed primitive types.

Prefer primitives to boxed primitives, and watch out for unintentional autoboxing.

Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing【the creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVM implementation】.

Avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight.

Code Example


Item 7: Eliminate obsolete(过时的) object references


An obsolete references is simply a reference that will never be dereferenced(间接引用) again.

Memory leaks(unintentional(无意的) object retentions(残留)) in garbage-collected languages are insidious(隐藏的), If an object reference is retained, not only is that object excluded from garbage collection, but so too are any objects referenced by that object, and so on.

"Obsolete_reference=null" to nulling out obsolete reference.

Nulling out object references should be the exception rather than the norm.

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.

Another common source of memory leaks is caches. WeakHashMap

A third common source of memory leaks is listeners and other callbacks.

Code Example


Item 8: Avoid finalizers and cleaners


Finalizers are unpredictable, often dangerous, and generally unnecessary. You should avoid them.

Cleaners are less dangerous than finalizers, but still unpredictable, slow, and generally unnecessary.

There is no guarantee they'll be executed promptly(立即). Never do anything time-critical in a finalizer or cleaner.

Providing a finalizer for a class can arbitrarily delay reclamation(回收) of its instances.

There is also no guarantee that finalizers or cleaners will run at all. Never depend on a finalizer or cleaner to update persistent state.

An uncaught exception thrown during finalization is ignored, and finalization of that object terminates. Uncaught exception can leave other objects in a corrupt(腐败的) state. An uncaught exception thrown during finalization will not terminate the thread nor print a warning.

There is a severe performance penalty for using finalizers and cleaners. This is primarily because finalizers inhibit(抑制) efficient garbage collection. (执行两次gc)

Finalizers have a serious security problem: they open your class up to finalizer attacks. If an exception is thrown from a constructor or its serialization equivalents---the readObject and readResolve methods, the finalizer of a malicious(恶意的) subclass can run on the partially constructed object that should have "died on the vine." This finalizer can record a reference to the object in a static field, preventing it from being garbage collected. Final class are immune(免疫的) to finalizer attacks. To protect nonfinal classed from finalizer attacks, write a final finalize method that does nothing.

Throwing an exception from a constructor should be sufficient to prevent an object form coming into existence; in the presence of finalizers, it is not. 

Have your class implement AutoCloseable.

Usages

To act as a safety net in case the owner of a resource neglects(疏忽) to call its close method.【FileInputStream, FileOutputStream, ThreadPoolExecutor, java.sql.Connection have finalizers that serve as safety nets】

Native peers.【待】

Cleaner code[待]

Summary

Don't use cleaners, or in releases prior to Java 9, finalizers, except as a safety net or to terminate noncritical native resources. Even then, beware the indeterminacy and performance consequences. 

Finalizer Demo

Cleaner Demo


Item 9: Prefer try-with-resources to try-finally


try-finally: exception in finally will completely obliterates the previous exception[result to debug hardly].

try-with-resources: resource implement the AutoCloseable interface.shorter and more readable, and provide far better diagnostics[latter exception is suppressed in favor of the former, and these suppressed are printed in the stack trace with a notation saying the were supressed].

Cleaner Demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,723评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,080评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,604评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,440评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,431评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,499评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,893评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,541评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,751评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,547评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,619评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,320评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,890评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,896评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,137评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,796评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,335评论 2 342