This is the 15th day of my participation in the August More text Challenge. For details, see: August More Text Challenge

preface

In general, it is better to reuse an object than to create a new object with the same functionality every time it is needed. Reuse is both faster and more popular. If an object is immutable (such as String), it can always be reused.

Starting from the String

We rarely do new String operations, so let’s take a look today

String patt =new String("^ [a zA - Z0-9] 29 {0} $");  // Don't do this!
Copy the code

Here’s what it looks like after you’ve written it in Idea, and you can see that new String is gray here, which means

This statement creates a new String instance each time it is executed, but the creation of these objects is unnecessary because strings cannot be made!

The improved version is as follows:

String pattern="^ [a zA - Z0-9] 29 {0} $";
Copy the code

This version uses only one instance of String, rather than creating a new instance each time it is executed. This object is reused for all code running in the same virtual machine, as long as they contain the same string literals.

This is where the JVM’s string constant pool comes in.

String w1 = "word";
String w2 = "word";
String b = new String("word"); 
Copy the code

First, we create three strings. Because of the pool, w1 and w2 are the same object reference!

System.out.println(w1 == w2);  // true 
Copy the code
System.out.println(w1 == b);   // false
Copy the code

The b variable is created by the constructor it uses, so it is not the same reference as w1!

b = b.intern(); // checks if pool contains this string, if not puts this string in pool, 
                // then returns reference of string from pool and stores it in `b` variable
Copy the code

Replace this variable with a variable from the variable pool.

System.out.println(w1 == b);   // true -> now b holds same reference as w1
Copy the code

To solve

Use the static factory method

You can often avoid creating unnecessary objects by using static factory methods instead of constructors. The constructor creates a new object each time it is called, while the factory method can dynamically adjust whether immutable or mutable objects are reused depending on your code.

Reuse mutable objects that are known not to be modified

Some objects are much more expensive to create than others. If you need such an “expensive Object to create” over and over again, it’s best to cache it for reuse. Unfortunately, it’s not always obvious when creating such objects.

Beware of unintentional autoboxing

Automatic packing allows us to mix basic types with basic packing types and automatically box and unbox as needed. The automatic packing mechanism blurs, but does not eliminate, the distinction between basic and packaging types. There are subtle differences in semantics, and there are obvious differences in performance. Consider the following method, which calculates the sum of all positive integers. To do this, the program must operate with long because int is not large enough to hold the sum of all positive ints:

The program got the right answer, but it was much slower than it should have been because of a one-character typographical error. The variable sum is declared as Long instead of Long, which means that the program constructs about 2312^{31}231 unnecessary instances of Long (roughly one each time Long I is added to the Long sum). Changing the declaration of sum from Long to Long reduces the runtime considerably. Use the wrapper type of the base type in preference to the wrapper type of the base type and beware of unintentional autoboxing.

conclusion

The key to this article is to get the balance right between creation and reuse. In modern JVM implementations, small object constructors do little explicit work, so small object creation and recycling costs are very low. It is usually a good thing to create additional objects that enhance the clarity, simplicity, or functionality of your program.

Maintaining your own object pool is still not recommended, as it is too risky, unless the objects in the pool are very heavyweight, such as database connections. The cost of establishing a connection is very high, so it makes sense to reuse these objects.