一 静态工厂 从现在开始,用静态工厂取代构造器吧
优点
以下是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