effective java · java

Creating and Destroying Objects:effective java ch2

Chapter 2. Creating and Destroying Objects
Item 1: Consider providing static factory methods instead of constructors
Item 2: Enforce the singleton property with a private constructor
Item 3: Enforce noninstantiability with a private constructor
Item 4: Avoid creating duplicate objects
Item 5: Eliminate obsolete object references
Item 6: Avoid finalizers

Item 1: Consider providing static factory methods instead of constructors
advantage:
  1- unlike constructors, they have names.
  2- unlike constructors, they are not required to create a new object each time they're invoked.
  3- unlike constructors, they can return an object of any subtype of their return type
disadvantage
   classes without public or protected constructors cannot be subclassed. 

Item 2: Enforce the singleton property with a private constructor

public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {  }
public static Elvis getInstance() {
return INSTANCE;
}

//for  deserialization or serialization
private Object readResolve() throws ObjectStreamException {
return INSTANCE;
}

}
1-Elvis.INSTANCE
2-Elvis.getInstance()

Item 3: Enforce noninstantiability with a private constructor
     utility classes were not designed to be instantiated
     noninstantiability by making a class abstract not work but by  private constructor

Item 4: Avoid creating duplicate objects ( performance improvement)
     You can often avoid creating duplicate objects by using static factory methods (Item 1) 

for(;;){
String s = new String("silly"); // DON'T DO THIS!
}
not involve mutable objects that are never modified once their values have been computed:

public class Person {
private final Date birthDate;
// Other fields omitted
}
public Person(Date birthDate) {
this.birthDate = birthDate;
}
// DON'T DO THIS!
public boolean isBabyBoomer() {
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;
}
improved one
class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/**
* 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;
}

Item 5: Eliminate obsolete object references (help garbage-collecter or every block of code must manages its own memory)
 null out references once they become obsolete.

public Object pop() {
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
improved one
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference
return result;
}

Item 6: Avoid finalizers
Finalizers are unpredictable, often dangerous, and generally unnecessary
 nothing time-critical should ever be done by a finalizer
 you should never depend on a finalizer to update critical persistent state.
 solution
 Just provide an explicit termination method like close =>InputStream ,cancel =>Timer ,Graphics.dispose
 Explicit termination methods are often used in combination with the try-finally construct to ensure prompt termination
 Foo foo = new Foo(...);
  try {
   // Do what must be done with foo
  ...
  } finally {
  foo.terminate(); // Explicit termination method
  }
Advertisements