[Java] [Read Effective Java] Chapter 2, Item 5 Avoid creating unnecessary objects

2 minute read

Avoid unnecessary object creation

As the title says. Careless creation of objects leads to poor performance. It’s a story that you should devise a little and write it so that useless objects are not generated.

Glossary

automatic boxing

There are two types in Java: primitive types (basic types) and reference types. You cannot put a primitive type, such as int, into a collection. Primitive values must be “boxed” into an appropriate wrapper class (Integer for int), as collections can only hold object references. When you retrieve the object from the collection, you get the stored Integer. If you need an int, you must “unbox” it from an Integer using the intValue method. Since the explicit implementation of this is a source of complexity, there are automatic boxing and unboxing functions in Java. Auto-boxing for automatic conversion of primitive type to wrapper class The automatic conversion from wrapper class to primitive type is called unboxing.

Primitive type Wrapper class
boolean Boolean
char Character
byte Byte
short Short
int Integer
long Long
float Float
double Double

immutable

An object whose state cannot be changed after it is created.

Sample code

This code creates a new String instance each time this part is executed.

Example 1


String s = new String("stringette"); // don't do this

If this is OK

Example 2


String s = "stringette";

Consider, for example, the Person class, which has an isBabyBoomer method that determines if the person is a baby boomer. With the way of writing ↓, every time the isBabyBoomer method is called, a new Calendar instance, TimeZone instance, boomStart, boomEnd Date instance is unnecessarily generated. This should not be done.

Example 3


public class Person {
    private final Date birthDate;

    // omit other fields, methods and constructors
    
    // Don't do this!
    public boolean isBabyBoomer() {
        // unnecessary creation of costly objects
        Calender gmtCal =
            Calender.getInstance(TimeZone.getTimeZone("GMT"));
        gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
        Date boomStart = gmtCal.getTime();
        gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
        Date boomEnd = gmtCal.getTime();
        return birthDate.compareTo(boomStart) >= 0 &&
               birthDate.compareTo(boomEnd) <0;
    }
}

Example 4 improved the bad points of Example 3. Once the class is initialized, it creates Calender instance, TimeZone instance, BoomStart, BoomEnd Date instance only once. This can be a significant performance improvement if the isBabyBoomer method is called frequently.

Example 4


public class Person {
    private final Date birthDate;

    // omit other fields, methods and constructors

    /**
     * Start and end dates for the baby boom.
     */
    private static final Date BOOM_START;
    private static final Date BOOM_END;

    static {
        Calender gmtCal =
            Calender.getInstance(TimeZone.getTimeZone("GMT");
        gmtCal.set(1946, Calender.JANUARY, 1, 0, 0, 0);
        BoomStart = gmtCal.getTime();
        gmtCal.set(1965, Calender.JANUARY, 1, 0, 0, 0);
        BoomEnd = gmtCal.getTime();
    }

    public boolean osBabyBoomer() {
        return birthDate.compareTo(BoomStart) >= 0 &&
               birthDate.compareTo(BoomEnd) <0;
    }
}

Example 5 is quite slow due to a typographical error. The variable sum is declared as Long instead of long. As a result, the program creates about 2^31 unnecessary Long instances. (Increases one instance each time long i is added to Long sum)

Lesson: Choose basic data types over boxed basic data types and beware of unintentional automatic boxing

Example 5


// A terribly slow program! Can you point out object creation?
public static void main(String[] args) {
    Long sum = OL;
    for (long i = 0; i <= Integer.MAX_VALUE; i++) {
        sum += i;
    }
    System.out.println(sum);
}

Continue

[Read Effective Java] Chapter 2, Item 6 “Remove obsolete object references” https://qiita.com/Natsukii/items/5f2edd6a9bcdb94b03e5