Java basic data type and integer cache mechanism

Time:2021-2-23

1、 8 basic data types (4 integer, 2 float, 1 character, 1 cloth)

Integer: byte (the smallest data type), short (short integer), int (integer), long (long integer);

Floating point type: float, double;

Character type: char (character type);

Boolean: Boolean.

2、 Value range

Data type name Occupied bytes Default value Min max Corresponding packaging
Integer type byte 1 0 -128(-2^7)~ 127(2^7-1) Byte
Integer type short 2 0 -32768(-2^15)~ 32767(2^15 – 1) Short
Integer type int 4 0 -2,147,483,648(-2^31)~ 2,147,483,647(2^31 – 1) Integer
Integer type long 8 0.0L -9,223,372,036,854,775,808(-2^63)~ 9,223,372,036,854,775,807(2^63 -1) Long
Floating point type float 4 0.0f 1.4E-45 ~ 3.4028235E38 Float
Floating point type double 8 0.0 4.9E-324 ~ 1.7976931348623157E308 Double
Character type char 2 empty \U0000 (i.e. 0) ~ \ uFFFF (i.e. 65535) Character
Boolean type boolean 1 flase True and false Boolean

3、 Cache mechanism of integer

Integer cache is a feature introduced in Java 5 to help save memory and improve performance.

Integer’s caching mechanism:Integer is used for small data (- 128)127) there is a cache. When the JVM is initialized, the data is – 128The number between 127 is cached in the local memoryIf the number between – 128 and 127 is initialized, it will be retrieved directly from the memory without creating a new object

First of all, let’s look at an example code using integer to show the caching behavior of integer.

    /**
    private static void testIntegerCache() {
        System.out.println("---int---");
        int a = 127, b = 127;
        System.out.println(a == b);         //true
        a = 128;
        b = 128;
        System.out.println(a == b);         //true

        System.out.println("---Integer---");
        Integer aa = 127, bb = 127;
        System.out.println(aa == bb);       //true
        aa = 128;
        bb = 128;
        System.out.println(aa == bb);       //false
        System.out.println(aa.equals(bb));  //true
    }

In Java 5, a new feature is introduced for integer operation to save memory and improve performance. Integer objects are cached and reused by using the same object reference in the internal implementation.

The above rules apply to the integer range – 128 to + 127.

The process that the java compiler automatically converts the original type to the encapsulated class is called autoboxing, which is equivalent to calling the valueof method.

Here is the code in JDK 1.8.0 build 25.

    /**
     * Returns an {@code Integer} instance representing the specified
     * {@code int} value.  If a new {@code Integer} instance is not
     * required, this method should generally be used in preference to
     * the constructor {@link #Integer(int)}, as this method is likely
     * to yield significantly better space and time performance by
     * caching frequently requested values.
     *
     * This method will always cache values in the range -128 to 127,
     * inclusive, and may cache other values outside of this range.
     *
     * @param  i an {@code int} value.
     * @return an {@code Integer} instance representing {@code i}.
     * @since  1.5
     */
    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

Before creating a new integer object, the IntegerCache.cache (is an array of type integer).

Integercache is a private static class in the integer class, which is responsible for the cache of integers.

    /**
     * Cache to support the object identity semantics of autoboxing for values between
     * -128 and 127 (inclusive) as required by JLS.
     *
     * The cache is initialized on first usage.  The size of the cache
     * may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
     * During VM initialization, java.lang.Integer.IntegerCache.high property
     * may be set and saved in the private system properties in the
     * sun.misc.VM class.
     */

    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() {}
    }

Javadoc detailed description of this class is used to achieve cache support, and support between – 128 to 127 automatic boxing process. The maximum value of 127 can be modified through the startup parameter – XX: autoboxcachemax = size of the JVM. Caching is implemented through a for loop. Create as many integers as possible from small to large and store them in an integer array called cache. This cache is initialized the first time the integer class is used. Later, you can use the instance objects contained in the cache instead of creating a new instance (in the case of auto boxing).

In fact, when this feature was introduced into Java 5, the range was fixed from – 128 to + 127. Later in Java 6, the maximum value was mapped to the java.lang.Integer . IntegerCache.high You can use the startup parameters of the JVM to set the maximum value. This allows us to flexibly adjust according to the actual situation of the application to improve performance. Why did you choose the range – 128 to 127? Because this range of integer values is the most widely used. The first time integer is used in a program, it also takes some extra time to initialize the cache.

Caching behavior in Java language specification

The Java language specification (JLS) in boxing conversion is as follows:

If the value of a variable p belongs to an integer (? 3.10.1) between – 128 and 127, a Boolean value (? 3.10.3) between true and false, and a character (? 3.10.4) between ‘u0000’ and ‘u007f’, we can directly use a = = B to judge whether the values of a and B are equal when we package P as two objects a and B.

Other cached objects

This caching behavior is not only applicable to integer objects. We have a similar caching mechanism for all classes of integer type.

There is a bytecache for caching byte objects

Shortcache is used to cache short objects

Longcache is used to cache long objects

There is a charactercache for caching character objects

Byte, short, long have a fixed range: – 128 to 127. For character, the range is 0 to 127. Except that integer can change the range by parameters, nothing else can.

4、 Floating point data

Floating point type refers to the data type used to represent decimal.

The difference between single precision and double precision is as follows

Single precision floating-point float, 32-bit storage, 1-bit sign bit, exponent 8-bit,Mantissa 23That is: the precision of float is 23 bits, which can accurately express the number of 23 bits. If it exceeds, it will be intercepted.

Double, 64 bit storage, 1 bit sign bit, 11 bit exponent, 52 bit mantissaThat is: the precision of double is 52 bits, which can accurately express the number of 52 bits. If it exceeds, it will be intercepted.

Double, a double precision type, has higher precision and larger representation range than float, which is often used in scientific calculation and other high precision occasions.

The difference between floating point numbers and decimals:

1) the precision of floating-point type is limited in assignment or storage. Float is 23 bits and double is 52 bits.

​ 2)In the actual process of computer processing and operation, floating-point numbers exist in binary form in essence.

3)There is a certain gap between two adjacent floating-point values that binary can represent. The larger the floating-point value is, the larger the gap will be. If you operate on a large floating-point number at this time, the accuracy of floating-point numbers will be affected, and even some “abnormal” phenomena will appear.

Why can’t floating point numbers be used to represent the amount

Let’s first draw a conclusion: the amount is BigDecimal

1) The problem of precision loss

As we can see from the above, the accuracy of float is 23 bits and that of double is 63 bits. In storage orOperation processWhen the precision is exceeded, the excess part will be cut off, which will cause error.

As for the amount, if we discard the part that can not be expressed, the loss will arise.

The 32-bit floating-point number consists of three parts: 1-bit sign bit, 8-bit exponent and 23 bit mantissa. This structure will be expressed as a binary decimal with 1 to the left of the decimal point and 2 as the base. The range of data size that can be represented by floating-point number is determined by the order code, but the precision of representation depends entirely on the length of mantissa. The maximum value of long is the 64th power of 2 minus 1, which needs 63 binary bits to represent. Even if it is double, the mantissa of 52 bits cannot fully represent the maximum value of long. The parts that cannot be expressed can only be discarded. As for the amount, the loss will arise if the part that cannot be expressed is discarded.

   after understanding the floating-point representation mechanism, the phenomenon of precision loss is not difficult to understand. But that’s just one of the reasons floating-point numbers don’t represent amounts. There is also a profound reason related to the conversion. Decimal 0.1 will be a wireless circular decimal in binary.

public class MyTest {  
    public static void main(String[] args) {  
        float increment = 0.1f;  
        float expected = 1;  
        float sum = 0;  
        for (int i = 0; i < 10; i++) {  
            sum += increment;  
            System.out.println(sum);  
        }  

        if (expected == sum) {  
            System.out.println("equal");  
        } else {  
            System.out.println("not equal ");  
        }  
    }  
}  

Output results:

0.1  
0.2  
0.3  
0.4  
0.5  
0.6  
0.70000005  
0.8000001  
0.9000001  
1.0000001  
not equal   

2) Base conversion error

We can see from the above,In the actual process of computer processing and operation, floating-point numbers exist in binary form in essence.

The decimal 0.1 in binary will be an infinite circular decimal, which will lead to errors.

If a decimal is not a negative integer power of 2, floating-point error is inevitable.

In other words:The finite decimals in a system are likely to be infinite decimals in B system,The error is also produced.

The root cause of imprecise floating-point numbers is that:The number of digits in mantissa is fixed. Once the precision of the number to be represented is higher than that of floating-point number, error will inevitably occur

The solution to this problem is the class of BigDecimal, which can represent any precision number. Its principle is: store the number with string, convert it into array to simulate large number, realize the mathematical operation of two arrays and return the result.

Key points of using BigDecimal:

1. BigDecimal variable initialization — must use the construction method of passing in string

`BigDecimal num1 = ``new` `BigDecimal(0.005);``//Convert numeric value to large number with error '` BigDecimal num12 =' ` new '` BigDecimal (' "0.005 ''); '/ / convert string to large number without error`

Because: not all floating-point numbers can be accurately expressed as a double type value, some floating-point values can not be accurately expressed as a double type value, it will be expressed as the nearest double In this case, it is used to initialize a large number, which will “cause error first, and then generate a large number with the error value”, that is, “make the mistake right”.

2. When using the division function to divide, you need to set various parameters, precise decimal places and rounding modes. There are eight rounding modes

1、ROUND_ UP(Always add the number in front of the non-zero discard part1).2、ROUND_ DOWN(Never add the number in front of the discarded part1That is, truncation).3、ROUND_ CEILINGBigDecimalIf it is positive, the rounding behavior is the same as round_ Up same;If it is negative, the rounding behavior is the same as round_ Down is the same.4、ROUND_ FLOORBigDecimalIf it is positive, the rounding behavior is the same as round_ Down same;If it is negative, the rounding behavior is the same as round_ Up is the same.5、ROUND_ HALF_ UP>= 0.5The rounding behavior is similar to round_ Up same;Otherwise, the rounding behavior is the same as round_ Down is the same.(rounding)6、ROUND_ HALF_ DOWN> 0.5The rounding behavior is similar to round_ Up same;Otherwise, the rounding behavior is the same as round_ Down same(Rounding)7、ROUND_ HALF_ EVEN;If it is even, the rounding behavior is the same as round_ HALF_ Down is the same.1Bit, then the result of this rounding method.1.15>1.2 1.25>1.2


8、ROUND_ UNNECESSARYArithmeticException

Classic interview questions

1. Short S1 = 1; S1 = S1 + 1; what’s wrong? Short S1 = 1; S1 + = 1; what’s wrong?

A: for short S1 = 1; S1 = S1 + 1, the type of the expression will be automatically promoted to int during the S1 + 1 operation, so there will be a type conversion error when assigning int to the variable S1 of short type.

For short S1 = 1; S1 + = 1, + = is an operator specified by java language. Java compiler will deal with it specially, so it can compile correctly.

2. Can char type variable store a Chinese man? Why?

Char type variable is used to store Unicode characters. Unicode character set contains Chinese characters, so char type can store Chinese characters. Another special case is that if a new character is not included in Unicode character set, char type cannot store the new character.

3. The difference between integer and int

Int is the eight built-in primitive data types of Java. Java provides an encapsulation class for each primitive type. Integer is the encapsulation class for int.

The default value of the int variable is 0, and the default value of the integer variable is null. This shows that integer can distinguish the difference between the unassigned value and the value of 0. For example, if one student fails to take the exam and the other student answers all wrong, the score of the first candidate should be null, and the score of the second candidate should be 0. On this point, integer is widely used. The integer class provides some methods for integer operations, such as the maximum and minimum values of integers used above.

4. Can the switch statement act on byte, long or string?

The storage range of byte is smaller than that of int, so it can be converted to int implicitly, so switch can act on byte

The storage range of long is larger than that of int, so it can’t be converted to int implicitly, it can only be cast, so switch can’t act on long

String cannot be used before version 1.7, and switch can be used on string after version 1.7

5. Is there x > x + 1? Why?

This is the critical value, when x = the maximum value; plus 1 (according to the binary operation + 1) will exceed its critical value, just will be its minimum value.

For example, byte 8 bits, – 128 ~ 127

127 binary: 0111 1111

1 binary: 0000 0001

Sum result: 10 million

Byte 8 bitsSigned, 10 million, just – 128

Reference

Java foundation – eight basic data types: integer, floating point, Boolean, character. What is the value range of byte, short, int, long in integer? What are single precision and double precision? Why can’t I use floating-point to represent the amount?

Understand the caching strategy of Java integer

This work adoptsCC agreementReprint must indicate the author and the link of this article