effective java(一)
本系列内容是学习effective java的理解和笔记。有一些内容在初次阅读的时候理解不深刻,或者完全不理解。因此先把内容要点记录下来,后续可以不断回顾这些笔记的内容,和多次查阅effectivejava来完善这些内容。
第一条:用静态工厂方法代替构造器
即用静态方法来获取对象,在构造器参数不多的时候可以使用这个方法。构造器参数多的话还是用建造者模式吧。
优势
- 第一大优势在于他们有名称
有名称的好处是在调用这些方法的时候可以通过名称来得知返回的类有什么区别 - 第二大优势在于不用在每次调用它们的时候都创建新对象
如果用new
来获取一个新的对象,那么每次都会创建新的对象,而用静态工厂方法的话,可以把第一次构造好的对象放在类的静态域内,然后重用,提高了性能。 - 第三大优势在于可以返回原返回类型的子类型对象
有一个父类,里头有一些内部类,我们出于安全或者其他目的,不想让人看见这个内部类的实现,我们就可以在这个父类中用静态方法返回这些内部类的对象 - 第四大优势在于返回对象的类可以随着每次调用而发生变化
意思和第三差不多但是更具体,就是说我们可以根据不同的情况(输入参数,硬件底层,版本更替等)来改变返回的对象,这些对象可能是枚举类,也可以是定义的返回的类的子类 - 第五大优势在于方法返回的对象所属的类,在编写包含静态工厂方法的类时可以不存在
意思和第三差不多,但是是非常非常具体的场景:我们可以提前设计好一个接口,这个接口约定了一些功能,然后其他人负责提供这些接口的不同实现。怎么获取这些实现呢,由于一个提供者来获取这个接口的实现,这个提供者也有接口,提供者的接口约定了要提供功能接口。比如说jdbc的实现,实际提供服务的是Connect,但是这个接口在设计的时候还未实现。获取这个服务的是Driver的connect方法,Driver也是一个未实现的接口。Mysql,Postgresql,Oracle分别实现了Connect服务和用以获取服务的Driver。
缺点
- 类如果不含共有的或者受保护的构造器,就不能被子类化(继承)
很明显是这样的 - 程序员很难发现他们
好像文档中没有特别强调静态方法
第二条:遇到多个构造器参数时要考虑使用构建器
有三种思路
- 采用重叠构造器
就是重载多个不同参数的构造器,其实并不是什么好办法,假如有5个参数,那至少要有五个构造器,还有你有我没有,我有你没有等等排列组合不同情况,构造器多到难以想象 - 使用javabean
即用setter来注入属性。这会造成先后set不同属性的时候,创建的对象会不一样,想一想就很恐怖。 - 构建器
通过一个构建器对象来创建你需要的对象。在参数多的时候这是个好办法。
第三条:用私有构造器或者枚举类型强化Singleton属性
有三种办法
- 静态final域成员
public class Elvis{
public static final Elvis INSTANCE = new Elvis();
private Elvis(){...};
public void leavTheBuilding(){...}
}
通过静态final来保证elvis的全局唯一性,但是会被有特权的客户端借助AccessibleObject.setAccessible()方法调用私有构造器。。。。闻所未闻,遇到以后再说8
2. 静态工厂方法
public class Elvis{
private static final Elvis INSTANCE = new Elvis();
private Elvis(){...};
public static Elvis getInstance(){return INSTANCE;}
public void leavTheBuilding(){...}
}
- 使用单类型枚举,更加优雅地实现这个功能
public enum Elvis{
INSTANCE;
public void leaveTheBuilding(){};
}