《Effective Java》 读书笔记(一) 使用静态构造方法代替传统构造函数
对象的创建与销毁
ITEM1 使用静态工厂方法代替构造函数
传统的新建一个对象的方法是通过构造函数:
Foo foo =new Foo();
一个类也可以提供一个静态方法产生一个对象:
Boolean flag=Boolean.valueOf(b);
这两种方法都可以产生一个对象,但是什么时候应该使用哪种方法?两种方法分别有什么优点和缺点呢?
对于使用静态方法产生一个对象来说:
1.静态方法可以自定义方法名
静态方法更能够通过方法名描述所返回的对象
有时候一个类包含多个构造函数,并且每个构造函数所产生的对象会稍微有些差别。那么使用静态方法产生一个对象是一个非常好的选择。
看以下代码:
BigInteger bigIntege=new BigInteger(int,int,Random);
如果不查看这个构造函数的文档,我们并不知道这个构造函数会返回一个具体什么样的BigInteger给我们。
但是:
BigInteger bigInteger=BigInteger.probablePrime(int,Random);
就能直接看出来,这样会产生一个素数对象。
PS:别过度使用静态方法,例如:
public class Base64{ public Base64 initByString(); public Base64 initByByte(); public Base64 initByInteger(); }
适当使用重载能让代码更简洁,也更方便使用。
2.静态方法不需要在每次被调用的时候都必须产生一个新的对象
就像众所周知的Integer等包装类,他们都含有自动装箱的功能:
Boolean flag=Boolean.valueOf(boolean);
这种静态方法对于创建比较大型的对象来说,可以很大程度的节省开销。
并且这种静态方法能够保证用户在任何时候,都是使用的同一个对象
3.静态方法可以返回原类型的任何子类型对象
这种方法基于接口实现的框架,可以用于隐藏API的具体实现。
在jdk1.8之前,接口不能定义静态方法,可以按照惯例定义一个不可实例化的Types的静态工厂方法用于返回对象。
就好像Java集合中的Collections一样。
4.静态方法可以根据参数返回不同的子对象
类似情况就像Integer的自动装箱,EnumSet等,会根据参数的大小,返回不同大小的对象一样。
5.静态方法返回的对象,在编写类时不是必须存在的
就像Java的数据库连接API JDBC一样,客户端只需要一个接口即可编写代码,而具体的实现在数据库的服务上。这样便实现了解耦操作
缺点:
1.如果类不含有公有或者受保护的构造函数,就不能被继承
刚开始看这段话,翻译过来比较生成,百度上也大多数直接翻译过来,并没有做过多的解释。
说说我的理解吧:
看下面一段代码:
public class Student { /** * 静态工厂方法构造对象 */ public static Student valueOf(){ return new Student(); } /** * 隐藏原本的构造函数 */ private Student(){} }
由于Student类的构造函数被定义为private的了。
因此:Student类就不能被作为父类被继承了。
2.对于编码人员来说,很难找到这个静态工厂构造方法具体是哪个.
比如有时候它可能叫valueOf,getInstance,from,of,create,newInstance,getType等。
程序员必须大概找找这个类的所有方法才能知道具体的静态构造函数是哪个。
总之,通常来说使用静态方法的构造函数是一个更好的选择,感悟并理解使用静态方法构造函数的优点,并在日常工作中使用它