Packaging type Java Language is an object-oriented language, but Java The basic data types in are not object-oriented, which is inconvenient in practical use. In order to solve this problem, a corresponding class is designed for each basic data type to represent when designing the class. In this way, the eight classes corresponding to the basic data type are called packaging classes(Wrapper Class). The packaging category is located in java.lang Packages, wrapper classes and basic data types are not described too much Of the eight class names, except Integer and Character After class, the class names of the other six classes are consistent with the basic data type, except that the first letter of the class name can be capitalized. Why do I need a wrapper class Many people will have questions, since Java In order to improve efficiency, eight basic data types are provided. Why do you need to provide packaging classes? In fact, there is an answer to this question, because Java Is an object-oriented language, many places need to use objects rather than basic data types. For example, in a collection class, we cannot int ,double And other types. Because the container of the collection requires that the element be Object Type. In order to make basic types have the characteristics of objects, packaging types appear. It is equivalent to "packaging" basic types, which makes them have the properties of objects, adds attributes and methods to them, and enriches the operations of basic types. 3,Unpacking and packing stay Java SE5 Before packing, you can use the following code: ```java Integer i = new Integer(10);
4. Automatic unpacking and automatic packing
In Java SE5, in order to reduce the work of developers, Java provides automatic unpacking and automatic packing functions.
Automatic packing: it is to automatically convert the basic data type into the corresponding packing class.
Automatic unpacking: This is to automatically convert the packaging class to the corresponding basic data type.
Integer i =10; //Automatic packing int b= i; //Automatic unpacking
Integer i=10 can replace Integer i = new Integer(10);, This is because Java provides us with the function of automatic boxing, and there is no need for developers to manually new an integer object.
5. Implementation principle of automatic packing and automatic unpacking
Since Java provides the ability of automatic disassembly and assembly of boxes, let's take a look at what the principle is and how Java realizes the function of automatic disassembly and assembly of boxes.
We have the following codes for automatic disassembly box:
public static void main(String[]args){ Integer integer=1; //Packing int i=integer; //Unpacking }
Decompile the above code to get the following code:
public static void main(String[]args){ Integer integer=Integer.valueOf(1); int i=integer.intValue(); }
It can be seen from the decompiled code above that the automatic boxing of int is through Integer Valueof () method. The automatic unpacking of Integer is realized through Integer Intvalue. If readers are interested, you can try to decompile all eight types, and you will find the following rules:
Automatic packing is implemented through the valueOf() method of the packing class Automatic unpacking is realized by wrapping the xxxValue() of the class object.
6. Where will the box be disassembled automatically
After we understand the principle, let's see under what circumstances Java will help us to automatically disassemble the box. The initialization and assignment of variables mentioned above will not be introduced, which is the simplest and easiest to understand.
Let's mainly look at the scenes that may be ignored.
Scenario 1: put the basic data type into the collection class
We know that collection classes in Java can only receive object types, so why doesn't the following code report an error?
List<Integer> li = new ArrayList<>(); for (int i = 1; i < 50; i ++){ li.add(i); }
Decompile the above code to get the following code:
List<Integer> li = new ArrayList<>(); for (int i = 1; i < 50; i += 2){ li.add(Integer.valueOf(i)); }
From the above, we can conclude that when we put the basic data type into the collection class, it will be automatically boxed.
Scenario 2. Size comparison between package type and basic type
Has anyone thought about what we actually compare when we compare the size of Integer objects with basic types? Look at the following code:
Integer a=1; System.out.println(a==1?"be equal to":"Not equal to"); Boolean bool=false; System.out.println(bool?"really":"false");
Decompile the above code to obtain the following code:
Integer a=1; System.out.println(a.intValue()==1?"be equal to":"Not equal to"); Boolean bool=false; System.out.println(bool.booleanValue?"really":"false");
It can be seen that the comparison operation between the packaging class and the basic data type is to unpack the packaging class into the basic data type, and then compare it.
Scenario 3. Packing type operation
Has anyone thought about how we perform four operations on Integer objects? Look at the following code:
Integer i = 10; Integer j = 20; System.out.println(i+j);
The decompiled code is as follows:
Integer i = Integer.valueOf(10); Integer j = Integer.valueOf(20); System.out.println(i.intValue() + j.intValue());
We found that the operation between two packaging types will be automatically unpacked into basic types.
Scenario 4. Use of ternary operators
This is a scene that many people don't know. The author also learned about it after an online bloody Bug occurred. Look at the code of a simple ternary operator:
boolean flag = true; Integer i = 0; int j = 1; int k = flag ? i : j;
Many people don't know. In fact, in int k = flag? i : j; In this line, automatic unpacking will occur. The decompiled code is as follows:
boolean flag = true; Integer i = Integer.valueOf(0); int j = 1; int k = flag ? i.intValue() : j;
This is actually the syntax specification of the ternary operator: when the second and third operands are the basic type and object respectively, the object will be unpacked for the basic type for operation.
Because in this example, flag? i : j; In the fragment, I in the second paragraph is an object of packing type, while J in the third paragraph is a basic type, so the packing class will be unpacked automatically. If the value of I is null at this time, NPE will occur for a long time. (abnormal null pointer caused by automatic unpacking)
Scenario 5: function parameters and return values
This is easy to understand and can be directly applied to the code:
//Automatic unpacking public int getNum1(Integer num) { return num; } //Automatic packing public Integer getNum2(int num) { return num; }
7. Automatic disassembly box and cache
The automatic disassembly box of Java SE also provides a function related to caching. Let's take a look at the following code and guess the output result:
public static void main(String... strings) { Integer integer1 = 3; Integer integer2 = 3; if (integer1 == integer2) System.out.println("integer1 == integer2"); else System.out.println("integer1 != integer2"); Integer integer3 = 300; Integer integer4 = 300; if (integer3 == integer4) System.out.println("integer3 == integer4"); else System.out.println("integer3 != integer4"); }
We generally believe that the results of the above two judgments are false. Although the compared values are equal, because the objects are compared and the object references are different, it will be considered that both if judgments are false.
In Java, = = compares object applications, while equals compares values.
Therefore, in this example, different objects have different references, so false will be returned when comparing. Oddly enough, two similar if conditions return different Boolean values.
The real output of the above code:
integer1 == integer2 integer3 != integer4
The reason is related to the caching mechanism in integer. In Java 5, a new function is introduced in the operation of integer to save memory and improve performance. Integer objects are cached and reused by using the same object reference.
For integer value range - 128 to + 127.
Only applicable to automatic packing. Creating objects using constructors is not applicable.
For specific code implementation, you can read the article on integer caching mechanism in Java, which will not be described here.
We only need to know that when automatic boxing is required, if the number is between - 128 and 127, the object in the cache will be used directly instead of re creating an object.
javadoc describes in detail that the cache supports the automatic boxing process between - 128 and 127. The maximum value of 127 can be modified by - XX:AutoBoxCacheMax=size.
In fact, when this function was introduced in Java 5, the range was fixed - 128 to + 127. Later, in Java 6, you can use Java lang.Integer. IntegerCache. High sets the maximum value.
This allows us to flexibly adjust according to the actual situation of the application to improve performance. What is the reason for choosing this - 128 to 127 range? Because this range of numbers is the most widely used. In the program, when Integer is used for the first time, it also takes some additional time to initialize the cache.
The Java language specification (JLS) in Boxing Conversion provides as follows:
If the value of a variable p is:
-Integer between 128 and 127 (§ 3.10.1)
Boolean values of true and false (§ 3.10.3)
Characters between '\ u0000' and '\ u007f' (§ 3.10.4)
When wrapping p into two objects a and b, you can directly use a==b to judge whether the values of a and b are equal.
8. Problems caused by automatic disassembly and assembly of box
Of course, the automatic disassembly and assembly of the box is a good function, which greatly saves the energy of developers and no longer needs to care about when the box needs to be disassembled. However, he will also introduce some problems.
For the value comparison of packaging objects, you can't simply use = =. Although the number between - 128 and 127 is OK, you still need to use equals comparison outside this range.
As mentioned earlier, some scenarios will perform automatic unpacking. At the same time, it was also said that due to automatic unpacking, if the packaging class object is null, NPE may be thrown during automatic unpacking.
If there are a large number of box disassembly operations in a for loop, a lot of resources will be wasted.
Common written questions:
Integer i1 =59; int i2 = 59; Integer i3 = Integer.valueOf(59); Integer i4 = new Integer(59); System.out.println(i1 == i2); true: When comparing the package type with the basic type, the package type is automatically unpacked as the basic type System.out.println(i1 == i3); true: The value 59 is in-128 Between 127 and 127, the cache mentioned above, so it is true,If the value is not-128 Between and 127 false System.out.println(i1 == i4); false: Reference types compare address values, which are different System.out.println(i2 == i3); true: i1 The source code is i3,i2 and i3 Comparison results and i2 And i1 The comparison results are the same, and the packing class and basic type are unpacked automatically System.out.println(i2 == i4); true: Automatic unpacking when comparing package type and basic type System.out.println(i3 == i4);with i1 == i4