1. 考虑用静态工厂方法替代构造器
- 有名称,根据名称可读性高;
- 减少不必要对象的创建;
- 可以返回原返回类型的任何子类型,返回对象会有很大的灵活性。
2. 遇到多个构造参数时候考虑使用构造器
如果一个类中的可选参数较多,为了可扩展性和代码的可阅读性可以考虑采用构造器创建类。
public class Tomato {
private String name = "";
private final int age;
private final int height;
public static Builder builder() {
return new Tomato.Builder();
}
private Tomato(Builder builder) {
name = builder.name;
age = builder.age;
height = builder.height;
}
@Override
public String toString() {
return "Tomato{" +
"name='" + name + '\'' +
", age=" + age +
", height=" + height +
'}';
}
public static class Builder {
private String name = "";
private int age = 0;
private int height = 0;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(int age) {
this.age = age;
return this;
}
public Builder height(int height) {
this.height = height;
return this;
}
public Tomato build() {
return new Tomato(this);
}
}
public static void main(String[] args) {
Tomato tomato=Tomato.builder().name("试").age(11).height(12).build();
System.out.println(tomato);
}
}
3.用私有化构造器或者枚举类型强化Singleton 属性。
- 私有化构造器
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public void leaveTheBuilding() {
System.out.println("Whoa baby, I'm outta here!");
}
// This code would normally appear outside the class!
public static void main(String[] args) {
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBuilding();
}
}
2.枚举类型
public enum Elvis {
INSTANCE;
public void leaveTheBuilding() {
System.out.println("Whoa baby, I'm outta here!");
}
// This code would normally appear outside the class!
public static void main(String[] args) {
Elvis elvis = Elvis.INSTANCE;
elvis.leaveTheBuilding();
}
}
4. 通过私有化构造器强化类不可实例化的能力
有些类是不需要进行实例化的。为了避免被实例化,将构造器进行私有化,如下代码,构造器中的异常是为了防止在类中被实例化。
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
throw new AssertionError();
}
}
5. 避免创建不必要的对象
最好能重用对象而不是每次需要的时候创建一个功能相同的对象;
如下代码块1 每次调用Person 的 isBabyBoomer 方法就会创建一个 Calendar 对象,一个TimeZone和两个Date 类 这些都是没有必要的,利用static静态代码块优化后的代码块2 可以避免这种情况。
public class Person {
private final Date birthDate;
public Person(Date birthDate) {
// Defensive copy - see Item 39
this.birthDate = new Date(birthDate.getTime());
}
// Other fields, methods omitted
// DON'T DO THIS!
public boolean isBabyBoomer() {
// Unnecessary allocation of expensive object
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0
&& birthDate.compareTo(boomEnd) < 0;
}
}
class Person {
private final Date birthDate;
public Person(Date birthDate) {
// Defensive copy - see Item 39
this.birthDate = new Date(birthDate.getTime());
}
// Other fields, methods
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0
&& birthDate.compareTo(BOOM_END) < 0;
}
}
6.消除过期对象的引用
- 一旦对象过期,就清除这些对象,清除对象只需要将这些对象置为空。
- 清空对象是一种例外,一般情况下不需要这么做,当类是由自己管理内存,这种情况要十分小心,一旦元素被释放掉,该元素包含的对象引用都应该被清空。
7. 避免使用终结方法
- 终结方法(finalizer)是不可预测的,是很危险的,一般情况下不要使用;
- 如果需要做一些终结,回收的事情,应该放在 try-finally 中。