美文网首页Android技术知识Android开发
Effective Java读书笔记 第一章

Effective Java读书笔记 第一章

作者: mrwangyong | 来源:发表于2016-10-08 16:08 被阅读184次

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

优点

以下是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

相关文章

网友评论

    本文标题:Effective Java读书笔记 第一章

    本文链接:https://www.haomeiwen.com/subject/egiuyttx.html