自动装箱拆箱概念
在Java SE 5之后,为基本数据类型提供了自动装箱和拆箱功能,使得将基本类型转换与对象之间的转换变得极其便捷。
| 基本数据类型 | 包装类 |
| int(4字节) | Integer |
| byte(1字节) | Byte |
| short(2字节) | Short |
| long(8字节) | Long |
| float(4字节) | Float |
| double (8字节) | Double |
| char(2字节) | Character |
| boolean(未定) | Boolean |
Integer i = 100;(拆箱)
int j = i;(装箱)
自动装箱拆箱的实现
Integer i = 100;(拆箱)
int j = i;(装箱)
//上面两行代码的反编译如下:
Integer i = Integer.valueOf(100);//拆箱
int j = i.intValue();//装箱
对于其他基本类型的装箱和拆箱和int类似。
案例分析
Integer
(1)案例
int a = 100;
int b = 100;
System.out.println(a == b);
int c = 200;
int d = 200;
System.out.println(c == d);
Integer e = new Integer(100);
System.out.println(a == e);
//结果
true
true
true
//反编译
byte a = 100;
byte b = 100;
System.out.println(a == b);
short c = 200;
short d = 200;
System.out.println(c == d);
Integer e = new Integer(100);
System.out.println(a == e.intValue());
如果改为下面的代码呢?
(2)案例
Integer a = 100;
Integer b = 100;
System.out.println(a == b);
//int c = 200;
Integer c = 200;
Integer d = 200;
System.out.println(c == d);//输出true
Integer e = new Integer(100);
System.out.println(a == e);
//结果
true
false
false
//反编译结果
Integer a = Integer.valueOf(100);
Integer b = Integer.valueOf(100);
System.out.println(a == b);
Integer c = Integer.valueOf(200);
Integer d = Integer.valueOf(200);
System.out.println(c == d);
Integer e = new Integer(100);
System.out.println(a == e);
(1)案例和(2)案例为啥不一样呢?
当 "=="运算符的两个操作数都是包装器类型的引用,则比较的是对象;而如果其中有一个操作数是表达式(即包含算术运算)或是基本类型则比较的是数值。
原因分析:我们查看一下valueOf()源码
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
//这里有个IntegerCache
return IntegerCache.cache[i + (-IntegerCache.low)];
//当大于high小于low时才新建
return new Integer(i);
}
//可以得知low=-128,high=127
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() {}
}
Boolean
boolean a = true;
boolean b = true;
System.out.println(a == b);
Boolean c = true;
Boolean d = true;
System.out.println(c == d);
//结果
true
true
//反编译
boolean a = true;
boolean b = true;
System.out.println(a == b);
Boolean c = Boolean.valueOf(true);
Boolean d = Boolean.valueOf(true);
System.out.println(c == d);
为什么是true?我们查看valueOf()源码
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
//注意TRUE和FALSE为常量
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
Double
double a = 1.0;
double b = 1.0;
System.out.println(a == b);
Double c = 1.0;
Double d = 1.0;
System.out.println(c == d);
//结果
true
false
//反编译
double a = 1.0D;
double b = 1.0D;
System.out.println(a == b);
Double c = Double.valueOf(1.0D);
Double d = Double.valueOf(1.0D);
System.out.println(c == d);
//valueOf()源码
public static Double valueOf(double d) {//创建了新对象
return new Double(d);
}
Long
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 321;
Integer f = 321;
Long g = 3L;
Long h = 2L;
System.out.println(c==d);//-127~128
System.out.println(e==f);//>128
System.out.println(c==(a+b));//自动拆箱
System.out.println(c.equals(a+b));//都是Integer类型
System.out.println(g==(a+b));//自动拆箱,向上转型为long
System.out.println(g.equals(a+b));//类型不匹配
System.out.println(g.equals(a+h));//向上转型为Long
//结果
true
false
true
true
true
false
true
//反编译
Integer a = Integer.valueOf(1);
Integer b = Integer.valueOf(2);
Integer c = Integer.valueOf(3);
Integer d = Integer.valueOf(3);
Integer e = Integer.valueOf(321);
Integer f = Integer.valueOf(321);
Long g = Long.valueOf(3L);
Long h = Long.valueOf(2L);
System.out.println(c == d);
System.out.println(e == f);
System.out.println(c.intValue() == a.intValue() + b.intValue());
System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));
System.out.println(g.longValue() == (long)(a.intValue() + b.intValue()));
System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));
System.out.println(g.equals(Long.valueOf((long)a.intValue() + h.longValue())));
//Long的equals
public boolean equals(Object obj) {
if (obj instanceof Long) {//类型不一样便是false
return value == ((Long)obj).longValue();
}
return false;
}
包装类型的大小比较
包装类型使用时注意点
谨慎包装类型的大小比较
public static void main(String[] args) {
Integer i = new Integer(100);
Integer j = new Integer(100);
// Integer j = 100;(或者如此)
compare(i,j);
}
//比较两个包装对象大小
public static void compare(Integer i , Integer j) {
System.out.println(i == j);
System.out.println(i > j);
System.out.println(i < j);
}
//结果
false
false
false
public static void main(String[] args) {
Integer i = new Integer(100);
Integer j = new Integer(100);
// Integer j = 100;(或者如此)
compare(i,j);
}
//比较两个包装对象大小
public static void compare(Integer i , int j) {
System.out.println(i == j);
System.out.println(i > j);
System.out.println(i < j);
}
//结果
true
false
false
提防包装类型的null值
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(null);
System.out.println(f(list));
}
public static int f(List<Integer> list) {
int count = 0;
for (Integer i : list) {
//必须对null进行处理
//count += (i!=null)?i:0;
count += i;
}
return count;
}
//结果
Exception in thread "main" java.lang.NullPointerException
来源:oschina
链接:https://my.oschina.net/u/2361475/blog/599242