本文主题:什么时候、如何创建对象?
1. 考虑用静态工厂方法代替构造函数
优点:
- 它与构造函数不同,它有名字,你可以把名字起的更易于阅读。
public class EffectiveJavaStudyTest {
public static void main(String[] args) {
//调用静态工厂方法获取实例
Complex complex=Complex.valueOf(1.2f,1.3f);
Complex complex1=Complex.valueOfPolar(1.2f,1.3f);
}
}
class Complex{
private final float re;
private final float im;
//构造函数
public Complex(float re, float im) {
this.re = re;
this.im = im;
}
//静态工厂方法1
public static Complex valueOf(float re, float im){
return new Complex(re, im);
}
//静态工厂方法2
public static Complex valueOfPolar(float r, float theta){
return new Complex((float)(r * Math.cos(theta)), (float)(r * Math.sin(theta)));
}
}
- 它与构造函数不同,它每次被调用时,不要求非得创建一个新的对象。
public class EffectiveJavaStudyTest {
public static void main(String[] args) {
//调用静态工厂方法获取实例
for (int i = 0; i < 2; i++) {
Complex complex=Complex.valueOf(1.2f,1.3f);
System.out.println(complex);
}
}
}
class Complex{
private final float re;
private final float im;
//单例
private static Complex COMPLEX=null;
//构造函数
public Complex(float re, float im) {
this.re = re;
this.im = im;
}
//静态工厂方法
public static Complex valueOf(float re, float im){
if (COMPLEX==null){
COMPLEX=new Complex(re,im);
}
return COMPLEX;
}
}
- 它与构造函数不同,它可以返回类型的子类型对象。
缺点:
-
类如果不含有公有或者受保护的构造函数,就不能被继承。设计一个类时,设计者是否希望这个类可被子类化(继承)或实例化,完全可以通过是否提供公有或者受保护的构造函数和构造函数的内容来控制。某种意义上这也限制了继承的滥用,而鼓励使用复合。
-
静态工厂方法和其他静态方法一样,一般要在API文档中作出特别的说明。在没有强烈的需要下,你还是应该使用规范的构造函数。
2. 使用私有构造函数强化singleton属性
singleton是指只能实例化一次的类,通常用来代表那些本质上具有唯一性的系统组件。实现方法有两种:都要把构造函数声明为私有的,并提供一个静态成员(方法/变量)用以访问该类的唯一实例。
- 方法一:公有静态成员是一个final域
public class EffectiveJavaStudyTest {
public static void main(String[] args) {
//调用静态工厂方法获取实例
for (int i = 0; i < 2; i++) {
Complex complex=Complex.COMPLEX;
System.out.println(complex);
}
}
}
class Complex{
//单例
public static final Complex COMPLEX=new Complex();
//私有构造函数
private Complex() {}
}
- 提供一个公有的静态工厂方法
public class EffectiveJavaStudyTest {
public static void main(String[] args) {
//调用静态工厂方法获取实例
for (int i = 0; i < 2; i++) {
Complex complex=Complex.getInstanse();
System.out.println(complex);
}
}
}
class Complex{
//私有
private static final Complex COMPLEX=new Complex();
//私有构造函数
private Complex() {}
//公有的静态方法
public static Complex getInstanse(){
return COMPLEX;
}
}