Effective Java读书笔记 第一章

一 静态工厂 从现在开始,用静态工厂取代构造器吧

优点

以下是Boolean类的valueOf的实现,其他包装类valueOf方法实现类似

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

可以看出 与一般的构造器相比 有以下优点

1..跟构造器相比,他们有名称;由于有名称,可以区分多个构造,解决多个构造不同对象的问题

2.可以做成单例的,不用每次都创建新的对象,优化性能,单例模式(valueOf不用每次都创建新的对象)

3.可以返回任何原返回类型的子类对象(自定义返回的对象类型)

4.在带参数的构造函数中,静态工厂更加简洁

public <K, V> HashMap<K, V> getInstance() {
       return new HashMap<K, V>(); 
}
调用
HashMap<String, Integer> instance = getInstance();
这招可用于findViewById这种类型转换频繁的操作

缺点

1.使用静态工厂,则类构造函数必须private,导致类无法继承,,,,,,,, 但是也催促着使用组合,代替继承(解耦)

2.与静态方法没有任何区分,只能是名字上.....让人无法直接一目了然,无法从方法名上明白这个是提供创建对象的;

规定:

valueOf: 代表类型转换的方法

of: valueOf更简洁的一种写法

getInstance: 返回唯一的单例对象,每个对象都是同一个对象;

newInstance: 返回每次重新创建的对象,每个对象都不一致

getType: 和getInstance一样,返回唯一的单例对象,但是一般返回不同的类使用,典型的就是一个父类返回不同的子类,用type代表子类类型

newType: 和newInstance一样,返回不同的对象,但是一般返回不同的类使用,典型的就是一个父类返回不同的子类,用type代表子类类型

二.创建对象时,需要传递很多参数时,可以用build去构建对象

1.当类有多个参数时,提供多个构造器,导致难以阅读,并且容易出错,自己多年开发经历,当一个方法参数超过4个的时候 基本上传入合适的参数就是一个痛苦的抉择,要一遍遍的比对当前的参数是否正确,相邻的两个参数如果类型一致还容易出错难以察觉

public class People {
  public String name;
  public int age;
  public int sex;
  public int num;
  public int phone;
  public String qq;
  public String weixin;

  public People(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public People(String name, int age, int sex, int num) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.num = num;
  }

  public People(String name, int age, int sex, int num, int phone, String qq, String weixin) {
    this.name = name;
    this.age = age;
    this.sex = sex;
    this.num = num;
    this.phone = phone;
    this.qq = qq;
    this.weixin = weixin;
  }
}  

这种调用最容易出错,并且必须不断的检查类型是否正确;

2.JavaBean模式,用set和get方法去一个个给参数赋值, 无法保证对象在赋值的过程中是同一个对象,并且,破坏了封装性,以后要找到哪里改变了参数值,如大海捞针;

People people=new People();
people.setAge(10);
people.setName("张三");
.......

3.build构建者模式去灵活构建不同的对象,不同的方法对应不同的参数,一目了然,而且,IDE自动提示,不容易出错

4.Builder对象模式,每次传递回当前的builder对象

不足:写法太繁琐,多创建对象耗费性能, 所以 最好 四个以上的参数时 使用builder模式

插一句:在Android中,由于性能限制,google建议我们不要写太多的get set方法,但是面向对象又必须实现对象的封装性,这里的建议是,javaBean内部调用字段的时候,不需要使用get set方法调用,外部调用的时候,一律都用get set方法,便于后期debug查找问题

也可以用set方法每次返回的都是当前对象这种模式来实现以上功能,这样不创建多余的对象,还能使用链式编程;

public class People {
  public String name;
  public int age;
  public int sex;
  public int num;
  public int phone;
  public String qq;
  public String weixin;

  public People() {
  }

  public People setName(String name) {
    this.name = name;
    return this;
  }

  public People setAge(int age) {
    this.age = age;
    return this;
  }

  public People setSex(int sex) {
    this.sex = sex;
    return this;
  }
}

调用
People people=new People().setAge(10).setName("张三");

三.单例模式的写法

默认的

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

JDK1.5 单例模式 推荐

 public enum  SingleInstance {
     NSTANCE;
 }  

四.如果需要编写全部都是静态方法的类,不需要被实例化,用私有构造器+抛异常来处理

public class UtilityClass {
// Suppress default constructor for noninstantiability
    private UtilityClass() {
        throw new AssertionError();
    }
}

五.尽量重用对象,不要创建不必要的对象

比如

String s=new String("abc");

此时,每次new出来,都是不同的对象,改为
String s="abc";
同一台JVM中,如果包含相同的字符串,就会重用对象

同样,用静态工厂方法,好过用new 因为静态工厂会重用对象 比如 Boolean.valueOf();代替new Boolean();

还有一点,在Android中,格式化时间,我们经常这样用

SimpleDateFormat dateFormat=new SimpleDateFormat("");

其实,这样每次都创建一个新的对象

SimpleDateFormat.getDateInstance();
SimpleDateFormat.getTimeInstance();

或者把simpleDataformat对象抽取成单例的使用

还有 防范自动装箱,不要在循环中将int转成Integer,优先使用基本类型而不是对象类型

六.消除过期的对象引用,防止内存泄露

1.在stack中,如果一个集合包含很多对象,记得将不可用的对象置为null,即弹栈(集合对象不可用时,记得把它置为null);

2.缓存导致的内存泄露,建议用java.lang.ref包下的各种软引用,弱引用等来包裹对象,方便垃圾回收;

3.监听器和回调导致的泄露,解决办法是一定要在生命周期结束时写上注销的方法,比如eventBus,广播等;

七.不要使用终结方法 finalize()

1.JVM不保证执行finalize()代码块里面的代码,优先级非常低,严重不推荐使用这个方法,更不推荐使用它来释放资源;
2.使用finalize()有严重的性能损失;

解决办法:主动提供一个终结的方法,用finally主动调用

FileInputStream inputStream=new FileInputStream();
try{
  //Do every thing;
}finally {
  close();
}

finalize和finally的区别,finally保证一定执行的,常用于关闭一些资源,finalize是Object类的一个方法,运行在回收对象之前做一些事情,不保证一定调用;
详细区别,请移步
finalize和finally的区别 http://www.cnblogs.com/xwdreamer/archive/2012/04/17/2454178.html

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

推荐阅读更多精彩内容

  • java笔记第一天 == 和 equals ==比较的比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量...
    jmychou阅读 1,490评论 0 3
  • 对象的创建与销毁 Item 1: 使用static工厂方法,而不是构造函数创建对象:仅仅是创建对象的方法,并非Fa...
    孙小磊阅读 1,969评论 0 3
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 1,046评论 0 4
  • Gzip是什么 复制大神们的解释吧: GZIP最早由Jean-loup Gailly和Mark Adler创建,用...
    岛民小强阅读 15,649评论 11 25
  • 1. 背景 事情是这样的,我准备编译android源码,但是我的MacPro只有256G的空间,而源码编译大概要1...
    WolfXu阅读 2,021评论 0 1