I don't believe you know the connection and difference between Integer wrapper type and int basic type

1. What is the packaging type?

Java introduces a corresponding packaging type for each basic data type. intThe packaging class is Integerthe automatic boxing/unboxing mechanism introduced since Java 5. The process of converting a basic type into a packaging type is called boxing ; The process of converting a wrapper type into a primitive type is called unboxing , making the two convertible to each other.

Java provides wrapper types for every primitive type:

  • Primitive type:boolean,char,byte,short,int,long,float,double

  • type of packaging:Boolean,Character,Byte,Short,Integer,Long,Float,Double

2. What is the difference between primitive types and wrapper types?

  1. Wrapper types can be null, while primitive types cannot.
  2. Wrapper types can be used with generics, while primitive types cannot. Generics can't use primitive types, because using primitive types will compile errors. Because generics are type-erased at compile time, only the original type is retained, and the original type can only be the Object class and its subclasses—primitive types are a special case.
List<int> list = new ArrayList<>(); // 提示 Syntax error, insert "Dimensions" to complete ReferenceType
List<Integer> list = new ArrayList<>();
复制代码
  1. Primitive types are more efficient than wrapper types. Primitive types store concrete values ​​directly on the stack, while wrapper types store references on the heap. Obviously, wrapper types take up more memory space than primitive types.

3. Explain auto-boxing and auto-unboxing?

Before explaining automatic boxing and automatic unboxing, let's first understand the Integer.valueOf()and IntegerCachemethods.

  • Integer.valueOf()
public static Integer valueOf(String s, int radix) throws NumberFormatException {
  		return Integer.valueOf(parseInt(s,radix));
 }
复制代码
/**
 * (1)在-128~127之内:静态常量池中cache数组是static final类型,cache数组对象会被存储于静态常量池中。
 * cache数组里面的元素却不是static final类型,而是cache[k] = new Integer(j++),
 * 那么这些元素是存储于堆中,只是cache数组对象存储的是指向了堆中的Integer对象(引用地址)
 * 
 * (2)在-128~127 之外:新建一个 Integer对象,并返回。
 */
public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high) {
        return IntegerCache.cache[i + (-IntegerCache.low)];
    }
    return new Integer(i);
}
复制代码

Call the Integer.valueOf()method , that is, if the value is in -128~127, then directly return the cachearray , otherwise call new Integer()to create the object.

  • IntegerCache
     /**
      * 缓存支持自动装箱的对象标识语义 -128和127(含)。
      * 缓存在第一次使用时初始化。 缓存的大小可以由-XX:AutoBoxCacheMax = <size>选项控制。
      * 在VM初始化期间,java.lang.Integer.IntegerCache.high属性可以设置并保存在私有系统属性中
     */
    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) {
                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);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++) {
                cache[k] = new Integer(j++); // 创建一个对象
            }
        }

        private IntegerCache() {}
    }
复制代码
  • Autoboxing: Convert primitive data types back to objects
public class Test {  
    public static void main(String[] args) {  
        // 声明一个Integer对象,用到了自动的装箱:解析为:Integer num = Integer.valueOf(9);
     Integer num = 9;
    }  
}  
复制代码

9是属于 int 基本数据类型的,原则上它是不能直接赋值给一个对象 Integer 的。但jdk1.5 开始引入了自动装箱/拆箱机制,就可以进行这样的声明,自动将基本数据类型转化为对应的封装类型,成为一个对象以后就可以调用对象所声明的所有的方法

  • 自动拆箱:将对象重新转化为基本数据类型
public class Test {  
     public static void main(String[] args) {  
         / /声明一个Integer对象
      Integer num = 9;
         
         // 进行计算时隐含的有自动拆箱
   	  System.out.print(num--);
     }  
 }  
复制代码

因为对象时不能直接进行运算的,而是要转化为基本数据类型后才能进行加减乘除

4、int 和 Integer 有什么区别?

  • Integer是int的包装类;int是基本数据类型;

  • Integer变量必须实例化后才能使用;int变量不需要;

  • Integer实际是对象的引用,指向此new的Integer对象;int是直接存储数据值 ;

  • Integer的默认值是null;int的默认值是0。

5、两个new生成的Integer变量的对比

Integer i = new Integer(10000);
Integer j = new Integer(10000);
System.out.print(i == j); //false
复制代码

由于Integer变量实际上是对一个Integer对象的引用,且生成的变量是位于堆上的,所以两个通过new生成的Integer变量永远是不相等的(因为new生成的是两个堆中对象,其内存地址不同)。

6、Integer变量和int变量的对比

int a = 10000;
Integer b = new Integer(10000);
Integer c=10000;
System.out.println(a == b); // true
System.out.println(a == c); // true
复制代码

Integer变量和int变量比较时,只要两个变量的值是向等的,则结果为true(因为包装类Integer和基本数据类型int比较时,java会自动拆包装为int,然后进行比较,实际上就变为两个int变量数值的比较

7、非new生成的Integer变量和new Integer()生成变量的对比

Integer b = new Integer(10000);
Integer c=10000;
System.out.println(b == c); // false
复制代码

非new生成的Integer变量和new Integer()生成的变量比较时,结果为false。(因为 Integer c=10000 等价于 Integer.valueOf(10000) ,如果其中的数值在 -128 ~ 127 之间的话,那么 c 指向的就是静态常量池中的对象,否则就是指向堆中所生成的对象。而 new Integer() 所生成的对象位于堆中,所以结果一定为 false

8、两个非new生成的Integer对象的对比

Integer i = 100;
Integer j = 100;
System.out.print(i == j); //true

Integer l = 128;
Integer r = 128;
System.out.print(l == r); //false
复制代码
  • 因为 Integer i =100 等价于 Integer.valueOf(100) ,由于其中的数值在 -128 ~ 127 之间,那么 i 和 j 指向的都是静态常量池中的对象,所以是同一个对象,所以结果为 true

  • 因为 Integer l =128 等价于 Integer.valueOf(128) ,由于其中的数值在 -128 ~ 127 之外,那么 l 和 r 指向的都是其各自在堆中生成的对象,所以是不同的对象,所以结果为 false

Guess you like

Origin juejin.im/post/7083875158661791752
Recommended