2.创建和销毁对象

1.使用静态工厂方法代替构造器

一般使用构造器(构造函数)创建对象实例,还可以使用静态工厂方法来创建对象实例。

优点

使用静态工厂方法代替构造器创建对象实例有以下优点:

1)静态构造方法的名称可以是更加有意义的,具有更好的可读性,而构造器的名称必须与类名称保持一致。

2)静态工厂方法不必在每次调用时都创建一个新对象,这对于那些需要重复创建相同对象的场景下尤其有用。

3)静态工厂方法可以返回原返回类型的任意子类型对象

4)静态工厂方法在创建参数化实例的时候,使程序更加简洁。

缺点

1)使用静态工厂方法创建实例的类,一般要求构造器是私有的,也就是说这个类不能被继承,不能被子类实例化。

2)静态工厂方法与其他静态方法并没有实质的区别,不能显而易见的判断某静态方法是不是工厂方法,所以,人们就做了一个约定,静态工厂方法有一些惯用名称:例如valueOf、of、getInstance、newInstance、getType、newType。

参考:1  2

2.遇到多个构造器参数时要考虑用构建器

如果类的构造器(或者静态工厂方法)有多个参数,并且这些参数中有些是可选参数时,就要考虑使用Builder模式。

3.通过私有构造器强化不可实例化的能力

有些工具类不希望被实例化,因为实例化对它来说没有什么意思,例如java.lang.Math,java.util.Arrays。有人通过将类定义为抽象类来避免类的实例化,不过,这样容易引起误解,让用户误以为这个类是专门为了继承而设计的。我们可以通过一个简单的方法来避免类被实例化,就是显式地将类的构造器声明为私有的(private),这样就保证避免类的实例化(前提是类中的其他成员不调用这个私有的构造器)。

4.避免创建不必要的对象

也就是说最好是能够重用已有的对象,而不是在每次需要的时候就创建一个相同功能的对象。

1)如果对象是不可变的(immutable),那它始终可以被重用。基本类型的包装类、String、BigInteger和BigDecimal都是不可变类。以字符串为例:

String str=new String("Java");

这条语句执行时,每次都会创建一个新的String实例,不过这是不必要的,因为每次创建的实例是相同的,都是字符串"Java",而“Java”本身就是字符串实例。如果这种方法用在循环或者被频繁调用的方法中,就会创建成千上万个相同功能的实例。改进后的版本如下:

String str="Java"

这种方法并没有创建新实例,而是使用已创建好的“Java”实例。并且,如果在代码的其他位置,使用了相同的字符串字面常量,仍然不会创建新对象,而是仍然复用这个“Java”实例,对于其他的不可变类也是如此。

2)除了重用不可变类之外,还可以重用那些创建了之后就不会修改的可变对象。参考

6.清除过期的对象引用(内存泄漏)

一个对象,如果在程序之后的执行过程中不会再使用,正常情况下,其所在的内存区域应该被回收,以便于存储新的对象。不过,由于一些原因未被回收,还是占据着内存,导致可用内存量下降,就像内存变少了一样,称这种现象为内存泄漏。Java虽然具有垃圾回收的功能,不过也会发生内存泄漏。

1)如果是类自身管理内存,可能会发生内存泄漏。以数组实现的栈为例,栈独自管理数组所占的内存空间,代码实现如下:

 

 1 public class Stack {
 2     private Object[] elements;
 3     private int size = 0;
 4     private static final int DEFAULT_INITIAL_CAPACITY = 100;
 5     public Stack() {
 6         elements = new Object[DEFAULT_INITIAL_CAPACITY];
 7     }
 8     public void push(Object e){
 9         ensureCapacity();
10         elements[size++] = e;
11     }
12     public Object pop(){
13         if(size == 0){
14             throw  new EmptyStackException();
15         }
16         return  elements[--size];
17     }
18     private void ensureCapacity(){
19         if(elements.length == size){
20             elements = Arrays.copyOf(elements, 2 * size + 1);
21         }
22     }
View Code

相关文章: