一、什么是包装类型
- Java 是一个近乎纯洁的面向对象编程语言,但8种基本数据类型不是对象。为了解决这个问题, 能够将这些基本数据类型当成对象操作,Java 为每一个基本数据类型都引入了对应的包装类型(wrapper class),int的包装类就是Integer,从JDK 1.5 开始引入了自动装箱/拆箱机制,使得二者可以相互转换。
- 原始数据类型和java泛型并不能配合使用。因为java的泛型某种程度上可以算作伪泛型,它完全是一种编译期的技巧,java编译期会自动将类型转换为对应的特定类型。这就决定了使用泛型,必须保证相应类型可以转换为Object。
原始类型: boolean,char, byte, short,int, long,float,double
包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,Double
二、如何操作
- 非自动装箱和拆箱
int A = 10;
// 装箱操作,新建一个 Integer 类型对象,将 A 的值放入对象的某个属性中
Integer BB = Integer.valueOf(A);
Integer CC = new Integer(A);
// 拆箱操作,将 Integer 对象中的值取出,放到一个基本数据类型中
int D = BB.intValue( );
- 自动装箱和拆箱
注意:自动装箱和自动拆箱是工作在编译期间的一种机制。
int A= 10;
Integer BB= A; // 自动装箱
Integer CC= (Integer)A; // 自动装箱
int j = BB; // 自动拆箱
int k = (int)BB; // 自动拆箱
三、Integer和int易错点------必看
看完上面的装箱拆箱的例子,你以为你会了吗,做个下面的练习你又发现自己不会了。
public static void main(String[] args) {
Integer aaa = new Integer(3);
Integer bbb = 3;//将3自动装指成Integer类型
int ccc=3;
System.out.println(aaa == bbb);// false 两个引用没有引用同一对象
System.out.println(aaa == ccc);// true aaa自动拆箱成int类型再和ccc比较
System.out.println(bbb == ccc);
Integer a1 = 6;
Integer a2 = 6;
int a11 = 6;
System.out.println(a1 == a2); //true
System.out.println(a1 == a11); //true
Integer a3 = 128;
Integer a4 = 128;
int a33 = 128;
System.out.println(a3 == a4); //false
//Integer会自动拆箱为int,所以为true
System.out.println(a3 == a33); //true
System.out.println(a3.equals(a4)); //true
Integer a5 = new Integer(6);
Integer a6 = new Integer(6);
System.out.println(a5 == a6); //false
System.out.println(a5.equals(a6)); //true
}
迷惑点:
Integer a1 = 6;
Integer a2 = 6;
System.out.println(a1 == a2); //true
Integer a3 = 128;
Integer a4 = 128;
System.out.println(a3 == a4); //false
如果不明就里很容易认为两个输出要么都是true 要么都是false。首先需要注意的是a1、a2、a3、a4 四个变量都是Integer 对象,所以下面的==运算比较的不是值而是引用。装箱的本质是什么呢?当我们给一个Integer 对象赋一个int 值的时候,会调用Integer 类的静态方法valueOf,如果看看valueOf 的源代码就知道发生了什么。
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);
}
由以上源码就会发现, 对于-128到127之间的数会进行缓存, Integer a1 = 6时,会将6进行缓存,下次再写Integer a2 = 6;时,就会直接从缓存中取,也就不用new一个对象了,所以a1和a2比较时就为true。
但a3和a4不在范围,超过范围会new一个对象,==是进行地址和值比较,是比较两个对象在JVM中的地址,这时a3和a4虽然值相同但地址是不一样的,所以比较就为false了。
总结:
- 两个都不是new出来的Integer,且数值在-128~127之间,用== 比较时,基本值相等时为true,超过范围就为false
- 两个都是new出来的Integer,用 == 比较时为false
- int和Integer比较,数值相同,用 == 比较时为true。因为Integer会自动拆箱为int去比较
- 如果要比较两个Integer对象的值,使用.equals()方法就好,或者可以通过.intValue()进行转换后来比较,
补充:
Boolean:(全部缓存)
Byte:(全部缓存)
Character(缓存范围’\u0000’到’\u007F’)(7f是十进制的127)
Short(-128 到 127缓存)
Long(-128 到 127缓存)
Float(没有缓存)
Doulbe(没有缓存)