Avoid creating unnecessary objects in Java.

Source: Internet
Author: User

Avoid creating unnecessary objects in Java.

Alan has recently read the textbook Java book, which contains a wealth of content. I will not introduce it much. I can only say one thing in silence, missing this book as a java developer will inevitably become a small pity, so it is recommended that you have time to read this book. I still cannot understand many things introduced in this book. Many things cannot be used in normal development, so I will not explain everything in detail, we will only extract some useful parts from our usual development and what little Alan can understand, as for some of the less practical and more advanced parts, we can only sort out the work experience and deep understanding of Alan and give it to some useful friends.

Article 5th of objective Java: Avoid creating unnecessary objects

We split the original article into several parts for understanding, achieving a small goal, and finally completely understanding the content of this part.

Part 1:In general, it is better to reuse objects instead of creating a new object with the same function every time you need it. Reuse methods are both fast and popular. If the object is unchangeable, it can always be reused.

Negative example:

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

Each time this statement is executed, a new String instance is created, but all the actions to create objects are unnecessary. The parameter ("") passed to the String constructor is a String instance, and its function is equivalent to all objects created by the constructor. If this method is used in a loop or in a frequently called method, thousands of unnecessary String instances are created.

Improved Version:

String s = "";

This version only uses one String instance, instead of creating a new String instance each time it is executed. Moreover, it ensures that all codes running on the same virtual machine will be reused as long as they contain the same string literal constants.

Extended thinking: ① when running in Java 1.7, Java will record the first instance in the frequently used pool when running in the method area. That is to say, it will save "Snap" in the constant pool ", so when you call String s = ""; next time, Java will directly return the reference of this object, instead of re-creating a new object, in this way, the memory overhead is reduced, and you can use it in a loop with peace of mind, and you are not afraid of frequent calls in methods. String s = new String (""); in fact, two objects are created, one being stored in the heap, and the other being "" in the constant pool ", s is only the reference of the object stored in the stack, while String s = ""; only one object is created and saved in the constant pool, then, you can save the reference of an object in the stack. (the Java Virtual Machine does not have a very deep understanding. If you have an incorrect understanding, please point it out. Thank you very much ).

Part 2:For immutable classes that provide both static factory methods and constructors, you can usually use static factory methods instead of constructors to avoid creating unnecessary objects. For example, the static factory method Boolean. valueOf (String) always takes precedence over the constructor Boolean (String ). The constructor creates a new object each time it is called, and the static factory method never requires this. In fact, it does not.

Expansion ideas:

1 package com. czgo. valid tive; 2 3/** 4 * use valueOf () static factory method instead of constructor 5 * @ author AlanLee 6 * @ version 2016/12/01 7*8 */9 public class Test {10 11 public static void main (String [] args) {12 // use the 13 Integer a1 = new Integer ("1"); 14 Integer a2 = new Integer ("1 "); 15 16 // use the valueOf () Static factory Method 17 Integer a3 = Integer. valueOf ("1"); 18 Integer a4 = Integer. valueOf ("1"); 19 20 // The result is false because a different object 21 System is created. out. println (a1 = a2); 22 23 // The result is true, because no new object is created 24 System. out. println (a3 = a4); 25} 26 27}

It can be seen that using the static factory method valueOf will not create a new object, so as to avoid creating a large number of unnecessary objects. In fact, many default valueOf methods of the class will not return a new instance, for example, the Boolean Type mentioned in the original article is not only the types provided by Java. If we have similar requirements during normal development, we may wish to imitate the static factory method provided by Java, we also define such static factory methods for our own classes to achieve object acquisition, so as to avoid repeated object creation, but we should not be overly superstitious about using static factory methods, this method also has its drawbacks (for more information about the static factory method, see article 1 in objective Java). This method is rarely used by individuals, generally, creating multiple objects in a class does not have much impact. You only need to pay attention to the usage.

Part 3:In addition to reusing immutable objects, you can also reuse variable objects that are not known to be modified. The examples written in the book are hard to understand. I didn't take the time to read them. I want to give you a similar example, and I don't know whether it means it or not. Please give me more advice!

Negative example:

1 package com. czgo. valid tive; 2 3 import java. SQL. connection; 4 import java. SQL. driverManager; 5 import java. SQL. SQLException; 6 7 public class DBUtilBad {8 private static final String URL = "jdbc: mysql: // 127.0.0.1: 3306/imooc"; 9 private static final String UNAME = "root "; 10 private static final String PWD = "root"; 11 12 public static Connection getConnection () {13 Connection conn = null; 14 try {15 // 1. load the driver 16 Class. forName ("com. mysql. jdbc. driver "); 17 // 2. obtain the database connection 18 conn = DriverManager. getConnection (URL, UNAME, PWD); 19} catch (ClassNotFoundException e) {20 e. printStackTrace (); 21} catch (SQLException e) {22 e. printStackTrace (); 23} 24 return conn; 25} 26}

The getConnection method provided by this class gets the JDBC database connection object. Each call to this method creates a conn instance. We know that in normal development, only one database connection object is required, it will not always be modified. There is no need to create a new connection object every time. I do not know if the program will encounter any unexpected situation when I create an instance every time, however, it is certain that this method affects the running performance of the program and increases the Garbage Collector burden on the Java Virtual Machine. We can improve it.

Improved Version:

1 package com. czgo. valid tive; 2 3 import java. SQL. connection; 4 import java. SQL. driverManager; 5 import java. SQL. SQLException; 6 7 public class DBUtil {8 private static final String URL = "jdbc: mysql: // 127.0.0.1: 3306/imooc"; 9 private static final String UNAME = "root "; 10 private static final String PWD = "root"; 11 12 private static Connection conn = null; 13 14 static {15 try {16 // 1. load the driver 17 Class. forName ("com. mysql. jdbc. driver "); 18 // 2. obtain the database connection 19 conn = DriverManager. getConnection (URL, UNAME, PWD); 20} catch (ClassNotFoundException e) {21 e. printStackTrace (); 22} catch (SQLException e) {23 e. printStackTrace (); 24} 25} 26 27 public static Connection getConnection () {28 return conn; 29} 30}

We use a static code block to create a conn instance. After improvement, we only create a conn instance once during class loading initialization, instead of creating a conn instance every time we call the getConnection method. If the getConnection method is frequently called and used, this method will significantly improve the performance of our program. In addition to improving performance, the meaning of the Code is clearer, making the code easier to understand.

Part 4:The keySet method of the Map interface returns the Set view of the Map object, which contains all the keys in the Map ). Rough looks like a new Set instance should be created every time the keySet object is called. However, for a given Map object, the same Set instance is actually returned every time the keySet object is called. Although the returned Set instance can be changed, all returned objects are functionally equivalent: when one of the returned objects changes, all other returned objects also need to change because they are supported by the same Map instance. Although creating multiple instances of the keySet view object is harmless, it is unnecessary. I am not particularly familiar with this part of content. I will post a piece of code for you to analyze. If you have friends who are familiar with this part, please leave your valuable experience. Thank you very much!

 1 package com.czgo.effective; 2  3 import java.util.HashMap; 4 import java.util.Iterator; 5 import java.util.Map; 6 import java.util.Set; 7  8 public class TestKeySet { 9 10     public static void main(String[] args) {11         12         Map<String,Object> map = new HashMap<String,Object>();13         map.put("A", "A");14         map.put("B", "B");15         map.put("C", "C");16         17         Set<String> set = map.keySet();18         Iterator<String> it = set.iterator();19         while(it.hasNext()){20             System.out.println(it.next()+"①");21         }22         23         System.out.println("---------------");24         25         map.put("D", "D");26         set = map.keySet();27         it = set.iterator();28         while(it.hasNext()){29             System.out.println(it.next()+"②");30         }31         32     }33 34 }

Part 5:There is a new method for creating redundant objects, called autoboxing, which allows programmers to mix basic types and basic types (Boxed Primitive Type <reference Type>, binning and unboxing automatically as needed. Automatic packing makes the difference between the basic type and the reference type blurred, but it is not completely eliminated. There are also subtle differences in semantics and obvious differences in performance. Consider the following program, which calculates the sum of all int values. For this reason, the program must use the long variable because int is not large enough to accommodate the sum of all int values:

 1 package com.czgo.effective; 2  3 public class TestLonglong { 4  5     public static void main(String[] args) { 6         Long sum = 0L; 7         for(long i = 0; i < Integer.MAX_VALUE; i++){ 8             sum += i; 9         }10         System.out.println(sum);11     }12     13 }

The result calculated by this program is correct, but it is much slower than the actual situation, only because one character is entered incorrectly. The sum variable is declared as Long rather than long, which means that the program constructs an extra Long instance to the power of 31 of about 2 (an instance is constructed every time a Long instance is added to long sum ). Change the declaration of sum from Long to long. The speed is not half past one. The conclusion is obvious: the basic type rather than the reference type should be used first, and the automatic packing should be careful.

Finally, do not mistakenly think that "Creating an object is very expensive. We should avoid creating an object as much as possible ". On the contrary, because the constructor of small objects only performs a small amount of Display Work, the creation and recycling of small objects is very cheap, especially in the modern JVM implementation. It is usually a good thing to improve program clarity, simplicity, and functionality by creating additional objects.

Conversely, it is not a good practice to avoid Object creation by maintaining your own Object pool, unless the objects in the pool are very heavyweight. A typical object example for correctly using the object pool is the database connection pool. The cost of establishing database connections is very expensive, so it makes sense to reuse these objects. Today's JVM (Java Virtual Machine) has a highly optimized garbage collector. If it is a lightweight object pool, it may not be as good as the garbage collector.

Here we will talk about "when you should reuse existing objects, please do not create new objects". On the contrary, we should also consider the question "when you should create a new object, do not reuse existing objects ". Sometimes the cost of Reusing an object is much higher than that of creating a duplicate object. If necessary, creating a new object instance will lead to potential errors and security vulnerabilities, and unnecessary object creation will only affect the style and performance of the program.

 

Conclusion: a person without a goal is doomed to fail. However, if the target is too large and you still cannot reach the target for a long time, you will feel tired, And then tend to slack off and may even give up your pursuit. If we break down a big goal into a specific small goal and achieve it one by one in stages, we can continue to taste the joy of success and then generate greater motivation to achieve the goal of the next stage. Therefore, in our daily work and study, we should have ambitious goals, but we must learn to split our goals into small ones. When my small goals cannot be achieved, I will first achieve my small goals. Slowly, the small goals that cannot be completed can be gradually achieved. Finally, it is not impossible to achieve our big goal. Without accumulating steps, without thousands of miles, without accumulating small streams, without rivers and rivers.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.