Interview question: Basic data type wrapper class int Integer

Because when learning collections, you know that the objects stored in the collection are all Object types, and you need to cast the type to the target type when you take them out (not necessary for using generic collections), such as int a = (Integer)arrayList.get(0); then We will find out, why cast to Integer instead of int? What is the difference between int and Integer?

1. The difference between the basic type and the packaging class

int is a basic type that stores values ​​directly; for example:

 

[java]  view plain copy  
 
  1. int i =  5; //Allocate space directly in the stack and store the value of 5  

 

Integer is a wrapper class for int, a class with methods; such as:

 

[java]  view plain copy  
 
  1. Integer i =  new Integer( 5);  //i is the reference variable of the object, so the object space is allocated in the heap memory, and the stack stores the address of the corresponding space in the heap memory  

 

Java has eight basic data types, corresponding to eight wrapper classes:

short Short

int Integer

long Long

char Character

byte Byte

float Float

boolean Boolean

double Double

The value of the variable is stored in the stack, and the object is stored in the heap. In comparison, the stack is more efficient, which is why Java retains basic types. The object created by the wrapper class can use some useful methods provided by the api. more powerful.

2. Automatic packing and unpacking

Then let's analyze the process of Integer i = 5;;

Before jdk1.5, such code was wrong and had to be implemented through a statement like Integer i = new Integer(5);; after jdk1.5, Java provided the function of auto-boxing, just Integer i = 5; Such a statement can implement the basic data type passed to its wrapper class, and the JVM executes Integer i = Integer.valueOf(5) for us; this is Java's automatic boxing.

Correspondingly, the process of taking out the basic data from the corresponding packaging class is unboxing; such as

Integer i = 5;

int j = i;//This process is automatic unboxing

In terms of source code, summarize the implementation process of packing and unpacking in one sentence:

The boxing process is implemented by calling the valueOf method of the wrapper, and the unboxing process is implemented by calling the xxxValue method of the wrapper . (xxx represents the corresponding basic data type)

Integer i = new Integer(xxx) and Integer i =xxx; The difference between these two methods:
1) The first method will not trigger the automatic boxing process; the second method will trigger;
2) In terms of execution efficiency and difference in resource usage. The execution efficiency and resource consumption of the second method are generally better than the first case (note that this is not absolute).

3. Source code questions, interview questions: (refer to http://www.cnblogs.com/dolphin0520/p/3780005.html)

a. Here is a question that often arises in interviews. Look at the following code:

 

[java]  view plain copy  
 
  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.            
  4.         Boolean i1 = false;  
  5.         Boolean i2 = false;  
  6.         Boolean i3 = true;  
  7.         Boolean i4 = true;  
  8.            
  9.         System.out.println(i1==i2);  
  10.         System.out.println(i3==i4);  
  11.     }  
  12. }  

What is the output?

 

true

false

The reason for this result can be explained by the source code:

 

[java]  view plain copy  
 
  1. public static Integer valueOf(int i) {  
  2.     if(i >= - 128 && i <= IntegerCache.high)  // If not set, IngegerCache.high defaults to 127  
  3.         return IntegerCache.cache[i + 128];  
  4.     else  
  5.         return new Integer(i);  
  6. }  

 

The implementation of the IntegerCache class is:

 

[java]  view plain copy  
 
  1. private static class IntegerCache {  
  2.         static final int high;  
  3.         static final Integer cache[];  
  4.   
  5.         static {  
  6.             final int low = -128;  
  7.   
  8.             // high value may be configured by property  
  9.             int h = 127;  
  10.             if (integerCacheHighPropValue != null) {  
  11.                 // Use Long.decode here to avoid invoking methods that  
  12.                 // require Integer's autoboxing cache to be initialized  
  13.                 int i = Long.decode(integerCacheHighPropValue).intValue();  
  14.                 i = Math.max(i, 127);  
  15.                 // Maximum array size is Integer.MAX_VALUE  
  16.                 h = Math.min(i, Integer.MAX_VALUE - -low);  
  17.             }  
  18.             high = h;  
  19.   
  20.             cache = new Integer[(high - low) + 1];  
  21.             int j = low;  
  22.             for(int k = 0; k < cache.length; k++)  
  23.                 cache[k] = new Integer(j++);  
  24.         }  
  25.   
  26.         private IntegerCache() {}  
  27.     }  

 As can be seen from these two pieces of code, when creating an Integer object through the valueOf method, if the value is between [-128, 127], it returns a reference to an object that already exists in IntegerCache.cache; otherwise, a new Integer object is created .
  In the above code, the value of i1 and i2 is 100, so the existing objects will be taken directly from the cache, so i1 and i2 point to the same object, while i3 and i4 point to different objects respectively.

 

 

b. If the four data types in the previous question are replaced by Double or Float, what is the result?

 

[java]  view plain copy  
 
  1. public static void main(String[] args) {  
  2.            
  3.         Double i1 = 100.0;  
  4.         Double i2 = 100.0;  
  5.         Double i3 = 200.0;  
  6.         Double i4 = 200.0;  
  7.            
  8.         System.out.println(i1==i2);  
  9.         System.out.println(i3==i4);  
  10.     }  
  11. }  

The answer is both false! As for the specific reason, readers can check the implementation of valueOf of the Double class.

 

  Here only explain why the valueOf method of the Double class adopts a different implementation from the valueOf method of the Integer class. Simple: the number of integer values ​​in a range is finite, while floating point numbers are not.
Note that the implementation of the valueOf method of the Integer, Short, Byte, Character, and Long classes is similar. The implementation of the valueOf method of Double and Float is similar.


c. What about Boolean?

 

[java]  view plain copy  
 
  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.            
  4.         Boolean i1 = false;  
  5.         Boolean i2 = false;  
  6.         Boolean i3 = true;  
  7.         Boolean i4 = true;  
  8.            
  9.         System.out.println(i1==i2);  
  10.         System.out.println(i3==i4);  
  11.     }  
  12. }  

The answer is both true!

 

As for why this is the result, you can see the source code of the Boolean class at a glance. The following is the specific implementation of Boolean's valueOf method:

 

[java]  view plain copy  
 
  1. public static Boolean valueOf(boolean b) {  
  2.         return (b ? TRUE : FALSE);  
  3.     }  

 

And what are TRUE and FALSE among them? There are 2 static member properties defined in Boolean:

 

[java]  view plain copy  
 
  1. public static final Boolean TRUE = new Boolean(true);  
  2.   
  3.    /**  
  4.     * The <code>Boolean</code> object corresponding to the primitive  
  5.     * value <code>false</code>.  
  6.     */  
  7.    public static final Boolean FALSE = new Boolean(false);  

 

At this point, everyone should understand why the above output results are true.

d. What does the following code output?

 

[java]  view plain copy  
 
  1. public class Main {  
  2.     public static void main(String[] args) {  
  3.            
  4.         Integer a = 1;  
  5.         Integer b = 2;  
  6.         Integer c = 3;  
  7.         Integer d = 3;  
  8.         Integer e =  321;  
  9.         Integer f = 321;  
  10.         Long g = 3L;  
  11.         Long h = 2L;  
  12.            
  13.         System.out.println(c==d);  
  14.         System.out.println(e==f);  
  15.         System.out.println(c==(a+b));  
  16.         System.out.println(c.equals(a+b));  
  17.         System.out.println(g==(a+b));  
  18.         System.out.println(g.equals(a+b));  
  19.         System.out.println(g.equals(a+h));  
  20.     }  
  21. }  

Don't look at the output first, the reader thinks about what the output of this code is. It should be noted here that when the two operands of the "==" operator are references of the wrapper type, the comparison points to the same object, and if one of the operands is an expression (ie. contains arithmetic operations) compares values ​​(that is, triggers an automatic unboxing process). Also, for wrapper types, the equals method does not perform type conversions. After understanding these two points, the above output results are clear at a glance:

 

 

true
false
true
true
true
false
true

 There is no doubt about the first and second output results. The third sentence will trigger the automatic unboxing process (the intValue method will be called) because a+b contains arithmetic operations, so they compare whether the values ​​are equal. For c.equals(a+b), the automatic unboxing process will be triggered first, and then the automatic boxing process will be triggered. That is to say, a+b will call the intValue method first, and after the value after the addition operation is obtained, it will call the Integer.valueOf method, and then compare equals. The same is true for the latter, but pay attention to the results of the penultimate and last output (if the value is of type int, the boxing process calls Integer.valueOf; if it is of type long, the Long called by boxing .valueOf method).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325385667&siteId=291194637
Recommended