[Read Effective Java] Chapter 2 Item 5 "Avoid the creation of unnecessary objects"

Avoid creating unnecessary objects

As the title says. Inadvertently creating objects leads to poor performance. Let's devise a little and write it so as not to generate useless objects.

Glossary

Automatic boxing

In Java, there are two types: primitive type (basic type) and reference type. Primitive types, such as ints, cannot be placed in a collection. Primitive values must be "boxed" into the appropriate wrapper class (Integer for int), as the collection can only hold object references. When you retrieve an object from the collection, you get the stored Integer. If you need an int, you need to "unbox" it from an Integer using the intValue method. Explicit implementation of this is a source of complexity, so Java has automatic boxing and unboxing features. Automatic boxing for automatic conversion of primitive type to wrapper class 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 will create a new String instance each time this part is executed.

Example 1


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

This is OK

Example 2


String s = "stringette";  

Consider, for example, the Person class with the isBabyBoomer method that determines if a person is a baby boomer. In the way of writing ↓, every time the isBabyBoomer method is called, a new Calender instance, TimeZone instance, boomStart, and boomEnd Date instance are created unnecessarily. Don't do this.

Example 3


public class Person {
    private final Date birthDate;

    //Omit other fields, methods and constructors
    
    //Don't do this!
    public boolean isBabyBoomer() {
        //Unnecessary generation 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. When the class is initialized, the Calender instance, TimeZone instance, BoomStart, and BoomEnd Date instances are created only once. This can be a significant performance boost if the isBabyBoomer method is called frequently.

Example 4


public class Person {
    private final Date birthDate;

    //Omit other fields, methods and constructors

    /**
     *Baby boom start and end dates.
     */
    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 one-letter typo. The variable sum is declared as Long instead of long. As a result, the program creates about 2 ^ 31 unnecessary Long instances. (Every time you add long i to Long sum, one instance increases)

Lesson: Choose a basic data type over a boxed basic data type and beware of unintended automatic boxing

Example 5


//A terrifyingly slow program! Can you point out the 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

Recommended Posts

[Read Effective Java] Chapter 2 Item 5 "Avoid the creation of unnecessary objects"
[Read Effective Java] Chapter 2 Item 7 "Avoid Finalizers"
[Read Effective Java] Chapter 3 Item 12 "Considering Implementation of Comparable"
[Effective Java] Avoid creating unnecessary objects
[Read Effective Java] Chapter 2 Item 1 "Consider static factory methods instead of constructors"
[Read Effective Java] Chapter 2 Item 6 "Remove obsolete object references"
[Read Effective Java] Chapter 2 Item 4 "Force uninstantiation with a private constructor"
[Read Effective Java] Chapter 3 Item 9 "When overriding equals, always override hashCode"
Item 71: Avoid unnecessary use of checked exceptions
Easily measure the size of Java Objects
[Read Effective Java] Chapter 2 Item 2 "Consider a builder when faced with a large number of constructor parameters"
Effective Java Chapter 2
Effective Java Chapter 6 34-35
Effective Java Chapter 4 15-22
Effective Java Chapter 3
Effective Java 3rd Edition Chapter 2 Object Creation and Disappearance
[Read Effective Java] Chapter 2 Item 3 "Force singleton characteristics with private constructor or enum type"
Effective Java 3rd Edition Chapter 3 Methods Common to All Objects
[Java] Creation of original annotation
The bad usage of "wave brackets" that Java professionals avoid depends on the rules, so let's read the rules.
Read the first 4 bytes of the Java class file and output CAFEBABE
[Java] Delete the elements of List
[Java version] The story of serialization
I read the source of ArrayList I read
Sort a List of Java objects
I read the source of Integer
Effective Java 3rd Edition Chapter 5 Generics
I read the source of Long
Effective Java 3rd Edition Chapter 8 Methods
I read the source of Short
I read the source of Byte
The origin of Java lambda expressions