`
kmakxa
  • 浏览: 14964 次
社区版块
存档分类
最新评论

阅读笔记---------Effective Java

 
阅读更多

创建和销毁对象:

1.静态工厂方法:提供一个静态方法用于返回对应的实例。感觉就像简单的工厂。工厂可以持有一个集合,根据请求返回对应的对象。这种方法的缺点是:被创建的对象要提供可以让外部访问的构造函数(感觉不是非常大的缺点啊,出了单例不然提供构造函数不是挺正常的吗?),还有方法看起来和其他静态方法一样,不好识别是构造函数(写一个好的函数名可以解决吧)。

2.构建器Bulider:当类有很多属性,在构建的时候就会遇到麻烦我们会需要根据不同的情况给某些属性初始值,这样就会造成构造函数必须有很多个进行重载,会形成很复杂不容易理解的情况。一种简单的方法是想javabean一样,提供一个无参的构造函数,然后为属性提供setter方法进行赋值。该种方法的缺点是整个构造过程被切分开了,如果在多线程的情况下,set属性的时候会遇到同步问题。解决方法是提供构建起Builder。代码如下:

public class Product {

private final String type;
private final String size;
private final String owner;

public static class Bulider {

private final String owner;
private String type = "nothing";
private String size = "0";

public Bulider(String owner){
this.owner = owner;
}
public Bulider type(String type){
this.type = type;
return this;
}
public Bulider size(String size){
this.size = size;
return this;
}
public Product bulid(){
return new Product(this);
}
}

private Product(Bulider bulider){
this.type = bulider.type;
this.size = bulider.size;
this.owner = bulider.owner;
}
}

Product是我们所需要构建的产品,该类只有一个私有的构造函数,利用Bulider进行初始化,也就是说外部无法直接实例化它。要实例化它要通过内部类Bulider,Bulider的静态公有的,有三个属性,其中owner是必须初始化的,type和size是初始化可选的,Bulider利用提供的和属性同名的方法来对其赋值。最后提供bulid方法,调用Product类的构造函数返回一个实例化Product。客户采用Product product = new Product.Bulider("Jack").type("rocket").size("large).bulid();来获得product,并且可以根据需要来初始化属性,可选择性的调用方法,顺序也没有要求,并且也很清楚的确定了设置了哪些属性和值。构建器的缺点是,要创建Product就必须先创建Bulider,带来了额外的开销。

3.强化Singleton属性:类仅仅提供一个static final的对象并不能保证只有一个实例,客户端可以通过AccessibleObject.setAccessible修改反射的权限,来调用私有的构造器。可以在构造器中做个判断解决。如果可序列化的话,还要保证不能序列化出两个,要在类中加入private Object readResolve{retrun Instance;}在类被反序列化的时候会调用该方法返回原来的实例。最简单的方法是实现只有一个单元素的枚举。

public enum Singleton{

INSTANCE;

}

4.私有构造器实现不可实例化:这个没什么特别好说的,就是如果有类不想实例化的时候,编写一个私有的构造器,里面抛出异常即可。

5.尽量的重用对象:这个就要通过经验判断,什么对象可以重用,就将其重用就是了,比较经典的就是数据库连接。

6.取消过期引用,这个是大部分c,c++程序员都比较清楚明白的原因,防止内存泄露。

7.尽量不用终结方法,用的话就好考虑能被调用到。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics