Java black box operation-automatic packing and unpacking, java black box operation packing

Source: Internet
Author: User

Java black box operation-automatic packing and unpacking, java black box operation packing

When I was writing an Android project, it is estimated that the most skillful words are:

  

List <Integer> list = new ArrayList <Integer> (); list. add (1); // add an integer to the int I = list in the set. get (0); // retrieve elements from the set

 

How easy it is to use ArrayList! At that time, I only knew that the angle brackets <> can only contain Object types starting with uppercase letters, but cannot contain int, char, and double primitive types. I have not studied the causes, this rule is so useful.

However, as I get tired of the brainless learning method of "codenon", I began to review the internal content of Java code.

The first thing is the ArrayList that each project must use. In my other blog, I have made a general analysis of the source code implementation of ArrayList. However, there are still several source codes that cannot be seen, but there are doubts that need to be solved urgently.

  

List <Integer> list = new ArrayList <Integer> ();

Each element in this code is of the Integer type. Therefore, when adding a new element to the list, it must be an Integer. For example, if you add a String to the list, a red line will appear below the code.
But this sentence list. add (1) As we all know, if you write a number without a decimal point in the Code, it is an int. If you add an int to a List with only Integer values, no error is returned, don't you think it's tricky?

Similarly, if int I = list. get (0) is used to retrieve the element with the index 0 in the list, it should also be an Integer. Why is the received variable an int? This is an obvious Type Mismatch Error!

I have heard of the concept of "Packaging class" before, but I have ignored it because I have always thought that Integer and Float are hard to hear, but they are just loaded and loaded, the reason is that the List does not accept the int or float type, so it is imperative to invent Integer or Float. Actually, it is useless.

I recently read a section in objective Java named "Prefer primitive types to boxed primitives ". There are a lot of examples of mixed primitive types and packaging types, which makes me dizzy. The following is a piece of code:
Long sum = 0L;for (long i = 0; i < Integer.MAX_VALUE; i++) {     sum += i;   }System.out.println(sum);
 

 

According to the book, this is a piece of code with low running efficiency. Can you see the problem?
Anyway, when I saw this code, I obviously felt that Java made some mistakes in converting the original type and the corresponding Object type during the compilation process ......

The topic of this article is AutoBoxing and Unboxing (Automatic Packing & Automatic unpacking)

Let's look at the simplest example:
Character ch = 'a'; // Character is the char packaging class.
 

 

There are no errors here. In fact, the compiler secretly converts the code into the following code During code optimization:
Character ch = Character.valueOf('a'); 
 

 

This means that the static method corresponding to the Character class is automatically called on the right side to construct a Character instance.
For further explanation, let's take a look at the valueOf method.
Public static Character valueOf (char c) {return c <128? SMALL_VALUES [c]: new Character (c);} // if the Character is in the buffer, directly retrieve the Character instance, otherwise, you need to reconstruct the private static final Character [] SMALL_VALUES = new Character [128]; // The class automatically carries a static buffer and stores the Character instance corresponding to the 128 common ASCII characters, avoid the trouble of re-constructing an instance every time static {for (int I = 0; I <128; I ++) {SMALL_VALUES [I] = new Character (char) I ); // call the constructor }}
 

 

Other packaging classes such as Integer have a static valueOf method. Each time the compiler checks that an int needs to be passed to an Integer, the code is automatically converted.
For example, in the above list. add (1), during the compilation process, the compiler finds that the parameter to be passed in is int, but the value to be received is Integer, so the code becomes:
list.add(Integer.valueOf(1));
 

 

The above is the auto-boxing process.

Automatic Packing usually occurs in two cases (taking int and Integer as examples ):
1. Use int as a method parameter, but the expected parameter in the method body is Integer;
2. During the value assignment, "=" indicates the Integer variable on the left and the int variable on the right.

In this way, the process of automatic unpacking becomes a logical step. See the following code:
public static int sumEven(List<Integer> li) {    int sum = 0;    for (Integer i: li)        if (i % 2 == 0)            sum += i;        return sum;}
 

 

After two unpacking operations are performed in the loop body, the compiler converts the code to the following:
public static int sumEven(List<Integer> li) {    int sum = 0;    for (Integer i: li)        if (i.intValue() % 2 == 0)            sum += i.intValue();        return sum;}
 

 

The intValue method of Integer is much simpler, and the encapsulated int value is directly returned.
@ Override public int intValue () {return value; // value is a member variable of Integer}
 

 


The use of automatic unpacking is the opposite of automatic packing. It is also used in the process of parameter transfer and value assignment, so we will not go into details here.

Let's analyze the super inefficient code, which should be like this after Automatic Disassembly and box conversion:

Long sum = Long. valueOf (0L); for (long I = 0; I <Integer. MAX_VALUE; I ++) {sum = Long. valueOf (sum. longValue () + I); // inefficient} System. out. println (sum. toString ());
 

 

In the loop body, there is only one simple sentence, and it actually contains one unpacking and one packing operation. After more than 2 billion cycles, the efficiency is incredible!
Since unpacking and packing can be regarded as "Inverse Calculation", why do extra operations need to be performed? Is it easier to directly use the original value calculation and then pack the data at a time?
Long sum = 0L;long s = sum; for (long i = 0; i < Integer.MAX_VALUE; i++) {     s += i;   }sum = Long.valueOf(s);System.out.println(sum);
 

 

References: https://docs.oracle.com/javase/tutorial/java/data/autoboxing.html

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.