• 序言

《effective java》可谓是java学习者心中的一本绝对不能不拜读的好书,她对于目标读者(有一点编程基础和开发经验)的人来说,由浅入深,言简意赅。每一章节都分为若干的条目,完全可以利用平时的零碎时间片来阅读和思考。仅仅是阅读了第二章,创建和销毁对象,从静态工厂、构造器等基础得不能再基础的知识,却使我有一种特别的感觉,就如同见到一位会使我怦然心动的女生,那种惊喜,是那么的美妙,却也是那么的震撼。原来女生还能够如此地美,原来书,所谓让人头晕的编程类书籍,可以写得如此地好,直击心灵,让人有相见恨晚的感觉。正如我在朋友圈写到的,阅书如品茗,品酒,如人生。她完全不同于《21天精通xxoo》的粗制滥造,也不像《Think in java》一样对于谁都高不可攀(我读起来有丝丝的苦涩)。

好了说太多了,现在开始正文吧。

更多精彩,请关注:http://muscle1990.com/?p=295

  • 创建和销毁对象

本章主题是讲述创建和销毁对象,何时以及如何创建,何时以及如何销毁对象,如何确保他们能够适时读销毁,,以及如何管理对象销毁之前必须进行的各种清理工作。

  • 第一条:考虑用静态工厂

我们先来看看这个静态工厂方法,返回累的实例:

public static Boolean valueOf(boolean b){
return b?Boolean.TRUE:Boolean.FALSE;
}

通过调用该方法,就可以非常方便地利用工厂得到实例。

静态工厂和构造器不同的优势在于:

  1. 她们有名称,as what you can see。
  2. 不需要每次调用他们的时候都创建一个新的对象。
  3. 她们可以灵活地返回原类型的任何子类型对象。
  4. 在创建参数化实例的时候,她使得代码变得更加的简洁。

for example:

在我们使用带参构造器创建一个map时,需要这样:

Map<String,String> stringMap=new HashMap<String,String>();

但是,假设HashMap提供以下静态工厂:

public static <K,V> HashMap<K,V> newInstance(){
return new HashMap<K,V>();
}

那么我们在创建map的时候,就可以这样写了:

Map<String,String> stringMap =HashMap.newInstance();

倘若你在工作中常需要做创建对象的事,会不会有一丝的惊喜呢?

  • 第二条:遇到多个构造器参数时需要考虑使用构建器:

静态工厂和构造器有个共同的局限性,都不能很好地扩增到大量可选属性。

考虑一个人的资料,有些是必须要的,如Id,name,有些是可选的,如地区、身高,体重等。

方法一,带参构造器

package new_and_destory_object;
/*
* @author 莫仕豪
* moshihao@gmail.com muscle1990.com
* @version:2013-7-31 下午9:53:36
*
*/ public class Person {
private String id;//必选
private String name;//必选 private int height;//可选
private int weight;//可选
//private xxx ooo;//可选
//and so on...//可选 public Person(String id,String name){
this.id=id;
this.name=name;
} public Person(String id,String name,int height){
this.id=id;
this.name=name;
this.height=height;
} public Person(String id,String name,int height,int weight){
this.id=id;
this.name=name;
this.height=height;
this.weight=weight;
}
public Person(String id,String name,int height,int weight,xxx ooo,...){
this.id=id;
this.name=name;
this.height=height;
this.weight=weight;
...
}
}

然而,在我们创建对象的时候,就会这样:

Person Muscle=new Person("helloworld","Muscle",172,55,........);

如果有很多属性呢?我参与的实际项目中,遇到过超过150个属性的。使用构造器设参方法,难道我需要写上百个?再慢慢选?慢慢填数据?再save?oh my god!

方法二:javaBean setter 模式

package new_and_destory_object;
/*
* @author 莫仕豪
* moshihao@gmail.com muscle1990.com
* @version:2013-7-31 下午9:53:36
*
*/
public class Person {
private String id;//必选
private String name;//必选 private int height;//可选
private int weight;//可选
//private xxx ooo;//可选
//and so on...//可选
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
//...
}

这种方法深信大家也不会陌生,然而,同样的情况,属性多呢。。。

Person Muscle = new Person();
Muscle.setId("helloworld");
...

除此之外,因为构造过程被分到几次的调用,所以javaBean会产生不一致的可能状态。

方法三:builder模式

幸运的是,还有第三种替代方法,既能够保持像重叠构造器那样安全,又能像javaBean那样易读灵活。

package new_and_destory_object;

/*
* @author 莫仕豪
* moshihao@gmail.com muscle1990.com
* @version:2013-7-31 下午9:53:36
*
*/
public class Person {
private String id;// 必选
private String name;// 必选 private int height;// 可选
private int weight;// 可选 // and so on... public static class Builder {
// 必选属性
private final String id;
private final String name;
// 可选
private int height =0;
private int weight =0;
// and so on... public Builder(String id,String name){
this.id=id;
this.name=name;
}
public Builder height(int height){
this.height=height;
return this;
}
public Builder weight(int weight){
this.weight=weight;
return this;
}
// and so on... public Person build(){
return new Person(this);
}
} public Person(Builder builder) {
id =builder.id;
name =builder.name;
height =builder.height;
weight =builder.weight;
}
}

注意Person是不可变的。下面的创建对象的实现:

Person Muscle = new Person.Builder("helloworld","Muscle").height(173).weight(55).build();

这样的代码,就会变得非常容易编写,并且简洁易懂。

  • 第三条:用私有构造器或者枚举类型强化单例属性。

    public class Singleton{
    private static final Singleton INSTANCE =new Singleton();
    private Singleton(){...} public static Singleton getInstance(){return INSTANCE;}
    }

这部分暂时没多大感觉,单例用得比较少,不过也学习了。

  • 第四条:通过私有构造器,强化不可实例化的能力。

这个讲得不错,在HSBC Gltc的Interview的时候有问到。

  • 第五条:避免创建不必要的对象

这部分写得特别受用,不多说,来码:

String s=new String("String");//永远不要这样写代码,求你了

赋值的String已经为对象实例,这样就是等于多了一个实例,如果是在比较频繁的String操作,这样会产生成千上万无用的实例。

String s="String";//这样就可以了,简洁明了不浪费

还需要将可重用的重用,正如同书中例子一样,起点时间,终点时间设为static final,这样就可以了,完全没有必要每一次调用都实例化。

装箱拆箱问题:

public static void main(String args[]){
//需要拆箱时间:16s
//基本类型时间:2s
Long sum =0L;
for(long i=0;i<Integer.MAX_VALUE;i++){
sum +=1;
}
System.out.println(sum);
}

倘若你还不知道Long和long的区别的话,简单点说就是Long是对象,long是基本类型,他们转换需要装箱拆箱。而效率从上可见一般,优先使用基本类型,不要手滑写错类型。。。

  • 第六条:

消除过期对象引用

package new_and_destory_object;

import java.util.Arrays;
import java.util.EmptyStackException;
/*
* @author 莫仕豪
* moshihao@gmail.com muscle1990.com
* @version:2013-7-31 下午11:13:52
*
*/ public class Stack {
public Object[] elements;
private int size =0;
private static final int DEFAULT_ININAL_CAPACITY =16; public Stack(){
elements=new Object[DEFAULT_ININAL_CAPACITY];
}
public void push(Object e){
ensureCapacity();
elements[size++]=e;
}
public Object pop(){
if(0==size){
throw new EmptyStackException();}
return elements[--size];
} private void ensureCapacity() {
if(elements.length == size){
elements =Arrays.copyOf(elements, 2 *size+1);
}
}
}

因为栈会维护对象的过期引用,了解JVM内存管理的应该明白,有引用的对象,就算明知道是垃圾,一样不会回收。所以这段代码就算运行没有一点问题,但是会有导致内存溢出的风险。

我们需要修改弹出栈的操作:

public Object pop(){
if(0==size){
throw new EmptyStackException();
}
Object result =elements[--size];
elements[size] =null;
return result;
}

一般而言,只要是类自己管理内存,我们就需要警惕内存泄漏的发生。

除此之外,我们还需要注意,内存泄漏的另一个常见的来源是缓存。一旦你把对象放到缓存中,就很容易被淡忘。

  • 第七条:避免使用终结方法:

老实说,没用过,但是了解一下也是好的

  • 结言:

effective java读书小记(一)创建和销毁对象,这篇读书笔记连想带码,用了差不多两个小时的时间,很久没有这样写过读书笔记了,学海无涯,书山有路,加油!

Muscle Mo 2013.7.31.晚写于大学城宿舍

effective java读书小记(一)创建和销毁对象的更多相关文章

  1. 【Effective Java读书笔记】创建和销毁对象(一):考虑使用静态工厂方法代替构造器

    类可以提供一个静态方法,返回类的一个静态实例,如Boolean包装类的一个获取实例的静态方法 public static Boolean valueOf(boolean b) { return (b ...

  2. Effective Java 读书笔记之一 创建和销毁对象

    一.考虑用静态工厂方法代替构造器 这里的静态工厂方法是指类中使用public static 修饰的方法,和设计模式的工厂方法模式没有任何关系.相对于使用共有的构造器来创建对象,静态工厂方法有几大优势: ...

  3. Effective Java(1)-创建和销毁对象

    Effective Java(1)-创建和销毁对象

  4. effective java 第2章-创建和销毁对象 读书笔记

    背景 去年就把这本javaer必读书--effective java中文版第二版 读完了,第一遍感觉比较肤浅,今年打算开始第二遍,顺便做一下笔记,后续会持续更新. 1.考虑用静态工厂方法替代构造器 优 ...

  5. Effective Java——(一)创建和销毁对象

    第一条 考虑用静态工厂方法代替构造器 什么叫静态工厂方法,就是通过在类中通过静态方法对对象初始化. 比如说 public class StaticFactory { private String na ...

  6. Effective Java 学习笔记之创建和销毁对象

    一.考虑用静态工厂方法代替构造器 1.此处的静态工厂方法是指返回指为类的对象的静态方法,而不是设计模式中的静态工厂方法. 2.静态工厂方法的优势有: a.使用不同的方法名称可显著地表明两个静态工厂方法 ...

  7. Effective Java(一)—— 创建和销毁对象

    在客户端(调用端)获取自身实例的方法: 公有的构造器: 类的静态工厂方法: 1. 使用静态工厂方法代替构造器 Boolean 是对基本类型 boolean 的包装类: public final cla ...

  8. 【Effective Java】第二章-创建和销毁对象——1.考虑用静态工厂方法代替构造器

    静态工厂方法的优点: 可以赋予一个具有明确含义的名称 可以复用唯一实例,不必每次新建 可以返回原实例类型的子类对象 可以在返回泛型实例时更加简洁 缺点: 类如果不含有共有的或者受保护的构造器,就不能被 ...

  9. 《Effective Java》读书笔记 - 2.创建和销毁对象

    Chapter 2 Creating and Destroying Objects item 1:Consider static factory methods instead of construc ...

随机推荐

  1. jQuery形式可以计算,它包含了无线电的变化价格,select价格变化,删除行动态计算加盟

    jQuery能够计算的表单,包含单选改变价格,select改变价格,动态加入删除行计算 各种表单情况的计算 演示 JavaScript Code <script type="text/ ...

  2. EF调用sp,EF自动生成返回类型

    在sp中添加下面的红色部分,就是执行sp时的返回类型,后面在EF中添加该sp后,EF会在DBContext文件中,自动生成调用该sp的代码,包括返回类型等,如下: public virtual Obj ...

  3. /proc/mtd 各参数的含义 -- linux内核

    经/proc虚拟文件系统读取MTD分区表:cat /proc/mtd mtd .name = raspi, .size = 0x00400000 (4M) .erasesize = 0x0001000 ...

  4. aul 学习测试(测量)

    -------------------aul5 ----------test0------------------------- select file#,rfile#,name from v$dat ...

  5. 最长公共子序列问题 (LCS)

    给定两个字符串S和T.求出这两个字符串最长的公共子序列的长度. 输入: n=4 m=4 s="abcd" t="becd" 输出: 3("bcd&qu ...

  6. Use PRODUCT_USER_PROFILE To Limit User

    The PRODUCT_USER_PROFILE (PUP) table provides product-level security that supplements the user-level ...

  7. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(11)-验证码实现和底层修改 ASP.NET MVC+EF框架+EasyUI实现权限管系列  (开篇)   (1):框架搭建    ...

  8. hdu1086(线段相交)

    题目意思: 给出n个线段,推断这n条线段中,线段相交的对数. http://acm.hdu.edu.cn/showproblem.php?pid=1086 题目分析: 此题主要写出推断线段相交的函数, ...

  9. JQUERY prop与attr差额

    1.  1-9-1之前和之后之间的差 <html> <script src="Js/jquery-1.9.0.js" type="text/javasc ...

  10. LinkedBlockingQueue多线程测试

    public class FillQueueThread extends Thread { private Queue queue; public FillQueueThread(Queue queu ...