Java basic data types and constant pool technology of packaging types

Basic data types in Java There are 8
basic data types in Java , namely:

  • 6 numeric types:
    • 4 integer types: byte , short , int , long
    • 2 floating point types: float , double
  • 1 character type: char
  • 1 boolean type: boolean . The default values ​​and the occupied space of
    these eight
    insert image description here
    basic data types are as follows: For boolean , the official document does not clearly define it, and it depends on the specific implementation of the JVM manufacturer. It is logically understood that it occupies 1 bit, but in practice, the computer's efficient storage factor will be considered.
    In addition, the size of the storage space occupied by each basic type of Java does not change with the change of machine hardware architecture like most other languages. This invariance in the size of the storage space occupied is one of the reasons why Java programs are more portable than programs written in most other languages ​​(mentioned in Section 2.2 of "Java Programming Thoughts").

Notice:

  1. The - type data used in Java must add L after the value, otherwise it will be parsed as an integer.
  2. char a = 'h'char:single quotes, String a = "hello":double quotes.
    These eight basic types have corresponding packaging classes: Byte, Short, Integer, Long, Float, Double, Character, Boolean.
    Wrapper types do not assign a value Null, while primitive types have default values ​​and do not Null.
    In addition, this problem suggestion can also be analyzed from the JVM level first.
    The basic data types are directly stored in the local variable table in the Java virtual machine stack, while the packaging type belongs to the object type, and the object instances all exist in the heap. Primitive data types take up very little space compared to object types.

"In-depth understanding of Java virtual machine": The local variable table mainly stores the basic data types
( boolean, byte, char, short, int, float, long, double) known at compile time, 对象引用(reference
type, which is different from the object itself, and may be a pointer to the start address of the object A reference pointer, which may also be a handle to a representative object or other location related to this object).

Constant pool technology for wrapper types

Most of the wrapper classes for Java primitive types implement constant pool technology.
Byte, Short, Integer, Longthese 4 wrapper classes create the corresponding type [-128,127]of , Charactercreate cache data with value in [0,127] the range , and Booleanreturn Trueor directly False.

Integer cache source code:

public static Integer valueOf(int i) {
    
    
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
private static class IntegerCache {
    
    
    static final int low = -128;
    static final int high;
    static {
    
    
        // high value may be configured by property
        int h = 127;
    }
}

Character cache source code:

public static Character valueOf(char c) {
    
    
    if (c <= 127) {
    
     // must cache
      return CharacterCache.cache[(int)c];
    }
    return new Character(c);
}

private static class CharacterCache {
    
    
    private CharacterCache(){
    
    }
    static final Character cache[] = new Character[127 + 1];
    static {
    
    
        for (int i = 0; i < cache.length; i++)
            cache[i] = new Character((char)i);
    }

}

Boolean cache source code:

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

If it exceeds the corresponding range, a new object will still be created. The size of the cache range is only a trade-off between performance and resources. The wrapper classes for the
two types of floating-point numbers do not implement the constant pool technology.FloatDouble

Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// 输出 true

Float i11 = 333f;
Float i22 = 333f;
System.out.println(i11 == i22);// 输出 false

Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出 false

Let's take a look at the problem. Is the output of the following code trueor false?

Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);

Integer i1=40Boxing occurs on this line of code, which means that this line of code is equivalent to Integer i1=Integer.valueOf(40). Therefore, i1the objects in the constant pool are used directly. Instead, Integer i2 = new Integer(40)the new object is created directly.
Therefore, the answer is false.
Remember: All value comparisons between integer wrapper class objects use the equals method for comparison.
insert image description here

The principle of automatic boxing and unboxing

What is automatic unboxing
  • Boxing : Wrap primitive types with their corresponding reference types;
  • Unboxing : converting a wrapper type to a primitive data type;
    for example:
Integer i = 10;  //装箱
int n = i;   //拆箱

The bytecode corresponding to the above two lines of code is:

   L1
    LINENUMBER 8 L1
    ALOAD 0
    BIPUSH 10
    INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
    PUTFIELD AutoBoxTest.i : Ljava/lang/Integer;
   L2
    LINENUMBER 9 L2
    ALOAD 0
    ALOAD 0
    GETFIELD AutoBoxTest.i : Ljava/lang/Integer;
    INVOKEVIRTUAL java/lang/Integer.intValue ()I
    PUTFIELD AutoBoxTest.n : I
    RETURN

From the bytecode, it can be found that boxing is actually calling valueOf()the method of the packaging class, and unboxing is actually calling xxxValue()the method .
therefore,

  • Integer i = 10Equivalent toInteger i = Integer.valueOf(10)
  • int n = iEquivalent to int n = i.intValue()
    Note : If the box is frequently unpacked, it will seriously affect the performance of the system. Unnecessary unpacking and unpacking operations should be avoided as much as possible.

おすすめ

転載: blog.csdn.net/qq_43939956/article/details/130504211