java boxing and unboxing

Every time I see a blog post which said that to stop and appreciate the source, I am very mixed feelings, my patience is not good people. Really I want to stop and read the source code, because maybe as the authors put it, "maybe you will find a good design it !!!"

I was soon my colleagues said, when they have learned not to look at the unofficial, official look. I still can not. The official is a must see, but unofficial or still turn, because I think a lot of unofficial write very vivid, even wonderful, impressive, from the author's words in other people's experience seriously, knowing it can become their own example.

Are in the same, why people can be so good, I you want to learn.

 

Digression

This morning in the learning company code, and ready to learn under the framework of MVP, he looked for a simple example of a framework MVP, results in a frame, found a class called SparseArray class, uphold the spirit of experiencing the problem go deeper I'll turn to see SparseArray relevant knowledge, and found a new world, incidentally, we studied a lot of Android in several collections, mainly SparseArray and ArrayMap, then I thought, Java was not with a lot of collections Well, for example HashMap, TreeMap, ArrayList, LinkList and so on, why Android still get another one do, not to mention Android itself is a Java-based, so I Pidianpidian find relevant information as a result, discovered an island (this should not be the New World, the amount hey!), the island is Java boxing and unboxing ,, in order to understand why Android but also specifically to get hold of their collections, so there is this article about the problem the answer lies in the conclusion of the article it! !

table of Contents

Small example for Consideration
source code and parse enjoy
boxing and unboxing timing
details of the problems caused by
small Conclusion

 

Thinking small example caused

public static void main(String[] args) {
        you i0 = 10;
        int i1=10;
        int i2=500;
        int i3=500;
        Integer i4=new Integer(10);
        Integer i5=new Integer(10);
        Integer i6=new Integer(500);
        Integer i7=new Integer(500);
        System.out.println("i0==i1?  "+(i0==i1));
        System.out.println("i2==i3?  "+(i2==i3));
        System.out.println("i4==i5?  "+(i4==i5));
        System.out.println("i6==i7?  "+(i6==i7));
    }

 

This is a very simple example, we look at its operating results

i0==i1? true 
i2==i3? true 
== i4 i5? false
i6==i7? false

 

How, and expected the same of you, this is mainly a knowledge point, Java, the basic type of comparison is == value, and package type == comparison is the address of the object, so the latter two is false.
Well, we then this code is altered,

   public static void main(String[] args) {
        Integer i8 = 40;
        Integer i9 = 40;
        Integer i10 = 500;
        Integer i11 = 500;
        Double d0 = 40.0;
        Double d1 = 40.0;
        Double d2 = 500.0;
        Double d3 = 500.0;
        System.out.println("i8==i9?  " + (i8 == i9));
        System.out.println("i10==i11?  " + (i10 == i11));
        System.out.println("d0==d1?  " + (d0 == d1));
        System.out.println("d2==d3?  " + (d2 == d3));
    }

 Let's look at the results, is not the way you envisioned it

i8==i9? true 
== I11 i10? false
d0==d1? false 
d2==d3? false

 

Hey, you're probably a little lost, it does not matter, then look down

  public static void main(String[] args) {
        Integer i12 = new Integer(40);
        Integer i13 = new Integer(40);
        Integer integer0 = new Integer(0);
        System.out.println("i12==i13?  " + (i12 == i13));
        System.out.println("i12==i13+integer0?  " + (i12 == i13 + integer0));
    }

 

The result may be what is it ....

i12==i13? false 
i12==i13+integer0? true

 

How, guessed Well, is not the look of Monga &% ¥ # @ *, all right, here we come to the next reason why in the end the answer is going to see this.

 

Source appreciation and resolve

Before appreciate the beauty (cao) wonderful (dan) of the Java source code, we first need to know is, jdk source where secretly gave us a boxing and unboxing work, the answer is valueOf () and xxxValue () two a method, you will find that whether or Short Integer or Double, etc., all have two methods, which in the Integer, xxxValue called the intValue, other similar, well, we now know the source where boxing and unboxing we go to the source to find out.
The first is of Integer

public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

 

In the Integer, valueOf three overloaded methods, but will eventually go to the above method parameters int, the code much, we simply look, first determine whether i get within a certain range, if you add conditions are met returns an array corresponding to the target value, Let us first whether the array is valid, and if the condition is not satisfied, then directly by i new a new Integer object.
The general process is said above, then we re-locate to IntegerCache class, this is an internal class Integer class, we see the inside of some Han

private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
        private IntegerCache() {}
    }

 Code is not much, stop and read line by line, first of all it declares a static three constants, a low initial value -128 Fu, a high not assigned, the default is 0 (here is also very easy to think of high 127), a Integer array (named cache, can more or less guess is used to doing, ~ ~ ~).
Next, is a static code block, to ensure that only loaded once, in this part of the code which, first of all to do is to assign high, because only when the statement of the assignment to low, then sun.misc.VM.getSavedProperty ( " java.lang.Integer.IntegerCache.high ") to obtain a value that is doing it, this is actually a private configuration file to obtain the value that can be configured to modify the JVM initialization time, will loaded, obtain the value assigned to i, 127 i and then compared, taking the maximum is assigned to i, and the maximum value of i and the then new Integer obtained compared, whichever is less, and then assigned to h , and finally assigned to high.
Simply put, high value is a value taken from the configuration file, but this value may be small, it may be large, after all, is a file, how much I want to configure it to configure how much, then get this after the value will be defined, if it is less than 127, then take 127, if it is greater than MAX_VALUE, then the value MAX_VALUE + low-1.
Good, then look down, and then opened up array cache address space, the size of high-low + 1, and then begins to initialize a value corresponding to index 0 from the low from the start (i.e. -128) increments. To this end.
Before the start of the ensuing discussion, assume that the value of the configuration file is the default, which is the ultimate high value of 127, then the cache array in the end play what role? The above code snippet binding valueOf you will find, if a given primitive type int value between -128 and 127, it would take directly to the cache array, if not within this range, then the object would be innovative to here you will understand the reasons why 40 and 500 when the two basic types of statements packaging type Integer (boxing), different values actually the result is not the same.
So the question is, so what good does it do this? Think about this question, int type you normally use is not mostly between -128 to 127, also said that this range is a "hot" range, in order to save memory overhead, the new value declared in the -128-127 when the package type Integer between, to get directly from the preloaded cache, the cache mechanism has been explained above, is taken from a cache array, it is not required to re--128-127 this range of new objects, new objects are required memory, without the caching mechanism, as long as the need is experiencing packing case, then all have to declare a new Integer object, but many still repeated, wasting a lot of memory, which is certainly not our I want to see. (Sigh, jdk source designer really pains ah!)
At this point, figure out boxed principle, let's go take a look at intValue method, unboxing is how to do, the source code is as follows

public int intValue() {
        return value;
    }

 Hey, only one line of code it really simple, this value is the value of an internal variable when declaring Integer object used directly back here to get the results after unpacking, but if you're careful, you'll also find similar shotValue, longValue the like, may be directly representative of other types of short to unpack.
Similarly, after packing understand the principle of Integer, I believe you should have guessed Byte or Long or Short implementation principle, not one by one we went to see a total of eight basic types, in which the byte, short, char, int , long five basic types of packing implement the principles and int are similar, although there is a little difference between them, but very much the same, we went to see not one, then left boolean and float and double, let's look in the Boolean

public static Boolean valueOf(boolean b) {
        return (b ? TRUE : FALSE);
    }

 Ah, looking very fresh, much more than simple Integer, hey, this, I will not explain it. Notes TRUE here is capitalized Oh, and lowercase true is not the same as, or long-winded forget about it, do not worry ah, here is an object TRUE, the following statement

public static final Boolean TRUE = new Boolean(true);

 You can see a static const object to ensure that there will be no repeat of the object, do not consume memory. Because Boolean is a more wonderful, after all, only two values, so do not like to get hold of as Integer caching mechanism.
Then there is the Float and Double, the two together because the two are similar, compared to Integer, the difference between them is that there is no use of caching mechanism, which is not provided with "hot" range, that is, think carefully about know, the plan to set up a "hot" range, then there is a good deal, because the accuracy of the problem may also harm than good, and with our own Float and Double in the development of relatively less used, so there is no caching policies, we still symbol the look of the Double valueOf method mean about it

public static Double valueOf(double d) {
        return new Double(d);
    }

 

Simple and crude, no matter what value you are, all to create a new type of packaging objects, Float exactly the same.
Well, now, go back and test to see before, you will understand why the same value is 40, Integer is true, and the Double is false, the reason is Integer packing uses caching policy, but Double not for treatment.
Then explain the last test case: why when I compare two values are equal objects, is false, but I would add the latter when an object is zero, then the comparison is true it really is unknown sleep Li Yeah, so, it raises the question of when packing and unpacking will happen then?

Packing opportunity unboxing

Assignment
package type calculation
....
In fact, this is a lot of opportunity, how to explain it, and then understand the principles, you really need to know is packing whenever encountered need to convert basic types of packaging type, packaging type to the base type when you need unpacking. Uphold this principle would not be what's doubt.
At this time, the last one, we look at the comparison of the code is just a test case of i12 == i13 + integer0, first of all look after the equal sign, two Integer object when added together, certainly can not be added up, so the java compiler will unpacking process is performed, which is substantially unpacking type int, and then obtained after the addition, and this is still the basic type int, and so when the former is also not compare, then the former also unpacking basic type int (i.e. when comparing int and Integer, Integer unpacking will), then == int number comparing two values found are equal, so the result is true.

Details of the problems caused by

See here, we have a more comprehensive understanding of boxing and unboxing, but I still have a question, so boxing and unboxing, for the actual developers, so what impact? As if I did not know before these things does not matter, still do my job, you know I do not know nothing on me, then I know why this thing?
Hey, you first need to understand the problem is that doing so is certainly justified. So what reason do? Look at an example

 Integer sum = 0;
    // int sum = 0; the same?
    for (int i = 0; i < 100; i++) {
        sum += i;
    }

 With the sum declared in the packaging loop iteration, as is the packaging can not be directly added to the basic type of type int i, so you need to unpack, together, and then packing, each time adding this needs to be process, then the time efficiency and use int compared to the statement, it is not a grade, so in development, to pay attention to these details.

 

Little Conclusion

Well, we go back to that question begins with the article, which is the reason for the birth of SparseArray, ArrayMap, and we usually are used in Java and other HashMap to store data, but there is a serious problem in the HashMap key and value are is generic, it will inevitably encounter boxing and unboxing process, and this process is very time-consuming, so in order to avoid boxing and unboxing improve efficiency, so the birth of SparseArray and other collections, but SparceArray efficiency high is conditional, it applies to a smaller amount of data scene, while in Android development, most of the scenes are relatively small amount of data, a lot of data in the case, of course, hashmap efficiency is excellent, but the specific SparseArray is how to achieve this I am going to get a separate article, interested can focus the next.
Well, so far the article also come to an end, say point the way, have to say, Java's design is very good, after all, a team effort, which is not, cache design today learned the Idea of a seemingly Integer class, Therefore, a small conclusion: nothing to look at the source, maybe you will find an excellent design too! ! !

 

Original link: https: //blog.csdn.net/hq942845204/article/details/81019902

Guess you like

Origin www.cnblogs.com/baxianhua/p/12160817.html