[Effective Java] Avoid creating unnecessary objects

Effective Java's own interpretation. I tried to interpret item 6 of the 3rd edition by writing my own code.

Overview

--Be aware of where the object is created. --Know the existence of the prepared object. --Constant objects that are reused with the same value over and over again. --Note that boxing creates objects unintentionally.

Examples and countermeasures for unnecessarily creating objects

String


  String s = new String("hoge");  

This code first creates an object with the letters ” hoge ”, then a new String (“hoge”) creates another object with the letters”hoge”. In short, objects with the same contents are created twice. By doing the following, you can create the object only once.


  String s = "hoge";  

Boolean The Boolean object can actually be created by taking the String object as an argument, as shown below.


  Boolean b = new Boolean("true");  

However, in the first place, Boolean takes only three values, null, true, and false. In the Boolean class, true and false objects are prepared in advance in the form of constants.

** Part of Boolean class **


    public static final Boolean TRUE = new Boolean(true);
    public static final Boolean FALSE = new Boolean(false);

There is also a valueOf method that returns these constants.


    public static Boolean valueOf(String s) {
        return parseBoolean(s) ? TRUE : FALSE;
    }

So, if you declare a Boolean object using the valueOf method as shown below, you don't need to refer to the object originally prepared in the Boolean class and create a new one.


  Boolean b = Boolean.valuOf("true");  

An object created each time a method is called

Consider the following method to determine if a string is a correct Roman numeral.


  static boolean isRomanNumeral(String s) {
    return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
              + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
  } 

Since String.matches internally creates a Pattern object, a new Pattern object will be created each time this method is called. If the Pattern object is defined as a constant in advance, the Pattern object can be created only once at the time of class initialization.


  public class RomanNumerals {
    private static final Pattern ROMAN = Pattern.compile(
              "^(?=.)M*(C[MD]|D?C{0,3})"
              + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
                
    static boolean isRomanNumeral(String s) {
      return ROMAN.matcher(s).matches();
    } 
  }

Unnecessary boxing

Consider the following code.


private static long sum() {
  Long sum = 0L;
  for (long i = 0; i <= Integer.MAX_VALUE; i++)
    sum += 1;
    
  return sum;
}

Since sum + = 1 is internally cast and calculated like Long sum = sum + (Long) 1 every time, a Long object is created every time. In the first place, this method does not require sum to be of type Long, so simply declaring sum of type long can greatly improve speed. This is a straightforward example, but you should always be aware of whether you need to use wrapper classes (need to take null, possible situations, etc.).

Caution

The idea is that the object of a method argument should not change state inside the method. This is because it is difficult to see what the object is in now, and the risk of bugs increases. Unless performance is required very much, in this case, we should give priority to reducing the risk of bug occurrence by creating a new object in the method and copying the contents of the argument object.

Recommended Posts

[Effective Java] Avoid creating unnecessary objects
[Read Effective Java] Chapter 2 Item 5 "Avoid the creation of unnecessary objects"
[Read Effective Java] Chapter 2 Item 7 "Avoid Finalizers"
Effective Java Chapter 2
Effective Java Chapter 6 34-35
Effective Java Chapter 4 15-22
Effective Java Chapter 3
[Read Effective Java] Chapter 2 Item 7 "Avoid Finalizers"
Item 71: Avoid unnecessary use of checked exceptions
java classes, instances, objects
Effective Java 3rd Edition Chapter 3 Methods Common to All Objects
Avoid Yubaba's error in Java
Creating ElasticSearch index from Java