int和Integer的区别
联系:
Java是一个近乎纯洁的面向对象编程语言,但是为了编程的方便还是引入了不是对象的基本数据类型,并且为了能够将这些基本数据类型当成对象操作,Java为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从JDK 1.5开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
区别:
1.int的默认值为0,Integer的默认值为null;
2.Integer必须实例化之后才可以使用,int类型则不需要;
3.Integer在new一个对象时,实际上是生成一个指针,指向该对象。而int则是直接存储数值。
4.在应用场景方面:在使用容器的时候,ArrayList等只能存放对象,不能使用基本数据类型,这时候就要使用Integer。再比如考试时零分和缺考的区别,使用int无法表示,但是Integer可以,缺考可以用null表示。
关于int和integer类型之间的转换和比较:
1.观察下面一段代码
public class Test {
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1 == i2); //true
System.out.println(i3 == i4); //false
}
}
按道理来说定义的格式,包装类型都相同,应该要么都是false,要么都是true,为什么会产生这样不同的结果呢?
== 比的其实是地址,因为i1,i2,i3,i4都是在栈上,保存的是对象的地址,而不是值。在给Integer对象赋一个int类型的值的时候,会发生自动装箱。这时会自动调用Integer类的静态方法valueOf()。点开valueOf()的源码就可以找到真相:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) //low在源码里定义是-128,high是127
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
所以可以看到如果字面量的值在-128到127之间,那么不会new新的Integer对象,而是直接引用常量池中的Integer对象。所以i1,i2引用的是常量池中的同一个对象,故地址相等。而给i3,i4装箱的字面值大于127,所以两个人都分别new了一个对象,地址自然不同。
2.integer变量之间的比较
Integer a = new Integer(10);
Integer b = new Integer(10);
System.out.println(a == b); // false
为什么是false呢?
因为两个Integer类型的变量比较的是地址,而通过new生成的对象每次都是不同的对象,不会跟上面那个例子一样去引用常量池中的同一个对象。不同的对象地址肯定不相等,所以是false。
3.Integer变量和int变量的比较
Integer a = new Integer(3);
Integer b = 3;
int c = 3;
System.out.println(a == b); // false
System.out.println(a == c); // true
通过上面的例子可以知道,这里的b引用的是常量池中的对象,而a指向的是堆上new的对象,二者比较地址时自然不相等。
那么c和a为什么相等呢?
因为Integer和基本数据类型int比较时,会自动拆箱为int,然后实际上就是两个int型之间的比较,值相等,二者就相等了。