(Transferred from: http://www.cnblogs.com/dolphin0520/p/3780005.html)
Automatic boxing and unpacking is a commonplace problem in Java, so let's take a look at some of the problems in boxing and unpacking today. This article first tells about boxing and unpacking the most basic things, and then look at the interview in the written test often encountered with the packing, unpacking related problems.
The following is the directory outline for this article:
A. What is boxing? What is unpacking?
Two. How the packing and unpacking is achieved
Three. Questions related to the interview
A. What is boxing? What is unpacking?
As mentioned in the previous article, Java provides a wrapper type for each of the basic data types, as for why the wrapper type for each of the basic data types is not elaborated here, and interested friends can access the relevant information. Before Java SE5, if you want to generate an integer object with a numeric value of 10, you must do this:
1 New Integer (10);
View Code
The auto-boxing feature is provided at the beginning of Java SE5, if you want to generate an integer object with a numeric value of 10, this is all you need:
1 Integer i = 10;
View Code
This process automatically creates the corresponding integer object based on the value, which is the boxing .
So what is unpacking? As the name implies, it corresponds to boxing, which is to automatically convert the wrapper type to the basic data type :
1 Integer i = ten; // Packing 2 int n = i; // Unpacking
View Code
Simply put, boxing is the automatic conversion of the base data type to the wrapper type; unpacking is the automatic conversion of the wrapper type to the base data type .
The following table is the wrapper type for the base data type:
two. How the packing and unpacking is achieved
In the previous section, after understanding the basic concept of boxing, this section examines how boxing and unpacking are implemented.
Let's take the Interger class as an example and look at the code below:
1 Public class Main {2 Public Static void Main (string[] args) {3 4 Integer i = ten; 5 int n = i; 6 }7 }
View Code
After you decompile the class file, you get the following:
The content of the bytecode obtained from the decompile can be seen as an integer valueof (int) method that is automatically called when boxing. The Intvalue method of integer is called automatically when unpacking.
Other similar, such as Double, Character, do not believe that friends can manually try.
So you can summarize the process of packing and unpacking in a sentence:
The boxing process is implemented by calling the wrapper's ValueOf method, and the unboxing process is implemented by invoking the wrapper's Xxxvalue method. (XXX represents the corresponding basic data type).
Three. Questions related to the interview
While most people are clear about the concept of boxing and unpacking, the question of packing and unpacking in interviews and written tests does not necessarily answer. Here are some common questions related to packing/unpacking.
1. What is the output of the following code?
1 Public classMain {2 Public Static voidMain (string[] args) {3 4Integer i1 = 100;5Integer i2 = 100;6Integer i3 = 200;7Integer I4 = 200;8 9System.out.println (i1==i2);TenSystem.out.println (i3==I4); One } A}
View Code
Maybe some friends will say it will output false, or some friends will say that it will output true. But in fact the output is:
true false
View Code
Why do you have such a result? The output shows that I1 and I2 point to the same object, while i3 and I4 point to different objects. At this point only a look at the source code will know, the following is an integer valueof method of the specific implementation:
1 Public Static Integer valueOf (int i) {2 if(i >= -128 && i <= Integercache.high)3 return integercache.cache[i + +]; 4 Else 5 return New Integer (i); 6 }
View Code
Where the Integercache class is implemented as:
1 Private Static classIntegercache {2 Static Final intHigh ;3 Static FinalInteger cache[];4 5 Static {6 Final intLow =-128;7 8 //High value is configured by property9 intH = 127;Ten if(Integercachehighpropvalue! =NULL) { One //Use Long.decode This avoid invoking methods that A //require Integer ' s autoboxing cache to be initialized - inti =Long.decode (Integercachehighpropvalue). Intvalue (); -i = Math.max (i, 127); the //Maximum array size is Integer.max_value -h = math.min (i, Integer.max_value--Low ); - } -High =h; + -Cache =Newinteger[(high-low) + 1]; + intj =Low ; A for(intk = 0; K < Cache.length; k++) atCACHE[K] =NewInteger (j + +); - } - - PrivateIntegercache () {} -}
View Code
As you can see from these 2 pieces of code, when you create an integer object by using the ValueOf method, if the value is between [-128,127], a reference to the object that already exists in Integercache.cache is returned, otherwise a new integer object is created.
The values for I1 and I2 in the above code are 100, so the objects that already exist are taken directly from the cache, so i1 and I2 point to the same object, while i3 and I4 point to different objects respectively.
2. What is the output of the following code?
1 Public classMain {2 Public Static voidMain (string[] args) {3 4Double I1 = 100.0;5Double i2 = 100.0;6Double i3 = 200.0;7Double I4 = 200.0;8 9System.out.println (i1==i2);TenSystem.out.println (i3==I4); One } A}
View Code
Some friends may think that the output of the above topic is the same, but in fact it is not. The actual output results are:
false false
View Code
As for the specific why, the reader can go to see the valueof of the double class.
This explains why the valueof method of the double class takes on a different implementation than the ValueOf method of the integer class. It is simple: the number of integer values in a range is limited, but floating-point numbers are not.
Note that the implementations of thevalueof methods of the classes Integer, short, Byte, Character, long are similar.
The implementation of the valueof method of Double and float is similar.
3. What is the result of this code output:
1 Public classMain {2 Public Static voidMain (string[] args) {3 4Boolean I1 =false;5Boolean i2 =false;6Boolean i3 =true;7Boolean I4 =true;8 9System.out.println (i1==i2);TenSystem.out.println (i3==I4); One } A}
View Code
The output is:
true true
View Code
As to why this is the result, similarly, the source code of the Boolean class will be seen at a glance. The following is a specific implementation of the Boolean valueof method:
1 Public Static Boolean ValueOf (boolean b) {2 return (b? True:false); 3 }
View Code
And what is TRUE and false? 2 static member properties are defined in Boolean:
1 Public Static FinalBoolean TRUE =NewBoolean (true);2 3 /** 4 * The <code>Boolean</code> object corresponding to the primitive5 * value <code>false</code>.6 */7 Public Static FinalBoolean FALSE =NewBoolean (false);
View Code
At this point, you should understand why the above output is true.
4. Talk about the integer i = new integer (XXX) and integer i =xxx, the difference between the two ways.
Of course, this topic belongs to a relatively broad category. But the main point must be answered, I summed up the following two points are the difference:
1) The first way does not trigger the automatic boxing process, while the second method will trigger;
2) difference in execution efficiency and resource occupancy. The second approach is more efficient and resource-intensive than the first case in general (note that this is not absolute).
5. What are the output results of the following program?
1 Public classMain {2 Public Static voidMain (string[] args) {3 4Integer A = 1;5Integer B = 2;6Integer C = 3;7Integer d = 3;8Integer e = 321;9Integer f = 321;TenLong g = 3L; OneLong h = 2L; A -System.out.println (c==d); -System.out.println (e==f); theSystem.out.println (c== (A +b)); -System.out.println (C.equals (A +b)); -System.out.println (g== (A +b)); -System.out.println (G.equals (A +b)); +System.out.println (G.equals (A +h)); - } +}
View Code
Don't look at the output, let the reader think about what the output of this code is. It is important to note that when the two operands of the "= =" operator are references to the wrapper type, it is whether the comparison points to the same object, and if one of the operands is an expression (that is, the arithmetic operation is included), the value is compared (that is, the process that triggers the automatic unboxing). Also, for wrapper types, the Equals method does not convert the type. Once you understand these 2 points, the above output will be at a glance:
1 true 2 false 3 true 4 true 5 true 6 false 7 true
View Code
The first and second outputs have no doubt. The third sentence because a+b contains arithmetic operations, it triggers the automatic unboxing process (which calls the Intvalue method), so they compare the values for equality. And for C.equals (A+B) will trigger the automatic unpacking process, and then trigger the automatic boxing process, that is a+b, will call the Intvalue method, the addition operation after the value, then call the Integer.valueof method, then the equals comparison. The same is true for the latter, but pay attention to the result of the second and last output (if the value is of type int, the boxing procedure calls integer.valueof; if it is a long type, the Long.valueof method of the boxing call).
Attach: View the implementation of the valueof of the Double class: implementation of the Double class in the JDK installation directory
\java\jdk1.6.0_14\src.zip\java\lang
Java Fundamentals--drill down into boxing and unpacking in Java