Avoid creating unnecessary objects in java

When we need a functionally equivalent object that exists in JVM, it is better to reuse instead of creating a new one.

For example:

String str = new String("upokary"); // DON'T DO THIS!

Instead, try the following improved version:

String str = "upokary"; 

More about avoid creating unnecessary objects

  • Instead of creating a new object each time it is needed, we can reuse it.
  • This can be both faster and more stylish
  • An object can always be reused if it is immutable.

Reuse mutable objects if it will not be modified.

When know something will not be modified, we can simply reuse the object like below:

public class Person {
    private final Date birthDate;
    
    // DON’T DO THIS!
    public boolean isAdultPerson() {
        // Unnecessary allocation of expensive object
        Calendar gmtCal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
        Date ageLimitStart = gmtCal.getTime();
        gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
        Date ageLimitEnd = gmtCal.getTime();
        return birthDate.compareTo(ageLimitStart) >= 0 && birthDate.compareTo(ageLimitEnd) < 0;
    }
}

Instead, try the following improved version:

class Person {
    private final Date birthDate;
    private static final Date AGE_LIMIT_START;
    private static final Date AGE_LIMIT_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 isAdultPerson() {
        return birthDate.compareTo(AGE_LIMIT_START) >= 0 &&
                birthDate.compareTo(AGE_LIMIT_END) < 0;
    }
}

How can we avoid unnecessary object creation?

We can avoid unnecessary object creation in multiple ways. Following are some approaches:

Approach #1: Use Static factory methods

By using static factory method we can avoid creating unnecessary objects. Following is a basic example:

Byte byteObject = new Byte( (byte) 55); // DON'T DO THIS!

Instead, try the following improved version:

Byte byteObject = Byte.valueOf( (byte) 55);

Approach #2: Prefer primitives to boxed primitives

Consider the following method from Effective Java book:

// Hideously slow program! Can you spot the object creation
public static void main(String[] args) {
    Long sum = 0L; // DON'T DO THIS!
    for(long i=0; i<=Integer.MAX_VALUE; i++){
        sum += i;
    }
    System.out.println(sum)
}

From the above method, sum is not a primitive type but of type Long (the wrapper class). sum += i will behind the scene create a new Long instance as it is an immutable class. So, it will somehow be equivalent to sum = new Long(sum.longValue() + 1).

Instead, try the following improved version:

public static void main(String[] args) {
    long sum = 0L; 
    for(long i=0; i<=Integer.MAX_VALUE; i++){
        sum += i;
    }
    System.out.println(sum)
}
  • Avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight.
  • Don't create a new object when you should reuse an existing one. Similarly don't reuse an existing object when you should create one