文章目录
int和Integer的区别:
- int是基本数据类型,直接存储的数值,默认是0
- Integer 是int的包装类,是个对象,存放的是对象的引用,必须实例化之后才能使用,默认是null
int和Integer比较的特性
== 地址比较
-
数值类型int自动装箱成对象Integer,实际上是调用了Integer.valueOf(),如果数值范围在-128到127会默认从常量池获取对象,引用地址相同;超过范围会new对象出来,在堆中重新分配内存,指向这个新内存的引用地址必然不相同。
-
int 和 Integer 比较时,会自动进行Integer的拆箱操作,即比较的是数值。
-
凡是new出来的对象,都在堆中重新分配内存,引用地址必然不相同。
equals 数值的比较
- Integer里重写了equals()方法,比较的是value。
- Object里默认的equals方法比较的是地址 ==
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
笔试题,关于 == 、 equals
//测试,结果是运行出来的哈
public static void compareInt2Integer() {
/**
* i、j实际上都是调用了 Integer.valueOf(128)
* 都是从常量池取的,所有内存地址一样,true
*/
Integer i = 127;
Integer j = 127;
System.out.println(i == j); // true
System.out.println(i.equals(j)); // true
/**
* m、n 实际上都是调用了 Integer.valueOf(128),进行自动装箱操作
* m、n 都是新创建的对象,会在堆中重新分配内存,地址不同,false
*/
Integer m = 128;
Integer n = 128;
System.out.println(m == n); //false
System.out.println(m.equals(n)); //true
/**
* k取的是缓存,h是新创建的对象,false
*/
Integer k = 127;
Integer h = new Integer(127);
System.out.println(k == h); //false
System.out.println(k.equals(h));//true
/**
* new 操作符会分配内存,a、b都是新创建的对象
* == 比较的是引用的地址,false
*/
Integer a = new Integer(127);
Integer b = new Integer(127);
System.out.println(k == h); //false
System.out.println(k.equals(h)); //true
/**
* Integer.valueOf() 会优先判断常量池缓存,缓存范围是-128到127,超过范围会new一个对象,
* w 实际也是调用了 Integer.valueOf(128)
* w、y 都是新创建的对象 false
*/
Integer w = 127;
Integer y = Integer.valueOf(127);
System.out.println(w == y); // true
System.out.println(w.equals(y)); //true
Integer w = 128;
Integer y = Integer.valueOf(128);
System.out.println(w == y); // false
System.out.println(w.equals(y)); //true
/**
* Integer和int == 比较,Integer会自动拆箱成int,数值比较,true
* Integer 和 int 进行算术运算符 + - * / 等,会自动拆箱
*/
Integer x = 128;
int z = 128;
System.out.println(x == z); //true
System.out.println(x.equals(z)); //true
}
自动装箱和拆箱
1、新建一个java文件,ClassTest.java
public class ClassTest {
public static void main(String[] args) {
Integer i = 10;
int a = i;
}
}
2、打开cmd,进入ClassTest.java路径下
javac ClassTest.java // javac,编译,生成class文件
javap -c ClassTest.class // javap 反编译
可以看出
- 自动装箱 是通过 Integer.valueOf()
- 自动拆箱是通过 Integer.intValue
Integer.valueOf() 自动装箱
享元模式,在 -128到127区间内,共享一份实例。
IntegerCache 是 Integer里的静态内部类
//Integer.valueOf() 自动装箱
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 final Integer cache[];
//静态变量,静态块,在类加载时初始化
static {
int h = 127;
//取自定义high,可配,如果没设置,默认为127
high = h;
cache = new Integer[(high - low) + 1]; //分配数组内存
int j = low;
//设置常量数组cache[],下标从0-255,存储内容为(-128)-(127)
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
Integer.intValue() 自动拆箱
// Integer的值就是存储在这个value里面
private final int value;
public int intValue() {
return value;
}
参考:
深入剖析Java中的装箱和拆箱