2017年9月22日 自动装箱和自动拆箱
java的8个基本类型
四种整数类型(byte、short、int、long)
两种浮点数类型(float、double)
一种字符类型(char)
一种布尔类型(boolean)
基本类型的对象是无法调用方法的,
需要使用对应的包装类型:
int(4字节) →→→→ Integer
byte(1字节)→→→→ Byte
short(2字节) →→→→Short
long(8字节) →→→→ Long
float(4字节) →→→→ Float
double(8字节)→→→→ Double
char(2字节) →→→→ Character
boolean(未定)→→→→ Boolean
在把编译器换成java1.4版本之后,会出现报错 1 package autoBoxDemo; 2 3 public class Demo1 { 4 public void doing(Object obj){ 5 6 } 7 8 9 public static void main(String[] args) { 10 Integer i = 10; // 引用类型 11 int n = i; // 基本类型 12 System.out.println(n); 13 Demo1 demo=new Demo1(); 14 demo.doing(i); 15 demo.doing(n); 16 } 17 18 }
首先是Interger i 不能赋值为10,自然n赋值为i的代码也会报错,
这里可以看到doing()的参数可以用i而不能用n,因为i 是引用类型,n是基本类型。
java 1.5版本之后就可以用自动装箱技术封装一些转换来完成自动装箱,则一下代码就不会报错
装箱
在jdk1.4版本中可以用以下代码实现类型转换
1.5版本之后系统是使用
int i =10;
Integer n1=Integer.valueOf(i);
进行装箱
1 public class Demo2 { 2 public static void main(String[] args) { 3 int i =10; 4 Integer n1=Integer.valueOf(i); 5 System.out.println(n1); 6 Integer n2 = new Integer (i); 7 System.out.println(n2); 8 Integer n3 = new Integer (10); 9 System.out.println(n3); 10 } 11 }
拆箱
1.5版本之后系统是使用
Integer n = new Integer (10);
int num1=n.intValue();
进行拆箱
1 public class Demo3 { 2 3 public static void main(String[] args) { 4 Integer n= Integer.valueOf(10); 5 int num1=n.intValue(); 6 System.out.println(num1); 7 8 } 9 }
两种类型的值的大小比较
“==” 比较的是引用地址,所以num1和num2的比较会是false,注意 这里num1和num2的创建是用的new Integer()
1 public class Demo4 { 2 /**比较值大小*/ 3 public static void main(String[] args) { 4 Integer num1=new Integer(10); 5 Integer num2=new Integer(10); 6 System.out.println(num1==num2); //输出为false 7 System.out.println(num1.equals(num2)); //输出为true 8 int i1 =10; 9 int i2=10; 10 System.out.println(i1==i2); //输出为true 11 } 12 }
而使用valueof()创建时则不同,这里等同于Integer num1 =10, Integer num2=10
这里 num1==num2 的结果就为true了
public class Demo5 { public static void main(String[] args) { Integer num1=Integer.valueOf(10); Integer num2=Integer.valueOf(10); System.out.println(num1==num2); //输出为true System.out.println(num1.equals(num2)); //输出为true } }
那么为什么会出现这样的不同呢,打开valueOf()方法的源代码
发现传入的参数给了一个最大和最小的区间,如果在区间内则从IntegerCache.cache中取出一个数字
如果不在 则new 一个Integer(i),再打开IntegerCache()的源码,发现给定的数值在[-128,127]之间
那么出现这样问题则可以理解为:
如果Integer的值是通过new Integer(number)创建的,则是创建了2个不同的对象,所以“==”的比较为false
而如果是用valueof()创建的如果数值在-128到127之间,那么则是从IntegerCache.cache中提取已经存放的数值,
引用地址是一样的,所以返回为true
1 public static Integer valueOf(int i) { 2 if (i >= IntegerCache.low && i <= IntegerCache.high) 3 return IntegerCache.cache[i + (-IntegerCache.low)]; 4 return new Integer(i); 5 }
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) { try { 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); } catch( NumberFormatException nfe) { // If the property cannot be parsed into an int, ignore it. } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.length; k++) cache[k] = new Integer(j++); // range [-128, 127] must be interned (JLS7 5.1.7) assert IntegerCache.high >= 127; } private IntegerCache() {} }
下面做一个测试:
1 public class Demo6 { 2 public static void main(String[] args) { 3 Integer num1=Integer.valueOf(127); 4 Integer num2=Integer.valueOf(127); 5 System.out.println(num1==num2); //结果:true 6 Integer num3=Integer.valueOf(128); 7 Integer num4=Integer.valueOf(128); 8 System.out.println(num3==num4); ////结果:false 9 } 10 }