一、基本类型
基本类型 | 位数 | 字节 | 包装器 |
---|---|---|---|
byte | 8位 | 1 | Byte |
boolean | true/false | 1 | Boolean |
char | 16位,存储Unicode码 | 2 | Character |
short | 16位 | 2 | Short |
int | 32位 | 4 | Integer |
float | 32位 | 4 | Float |
long | 64位 | 8 | Long |
double | 64位 | 8 | Double |
二、自动装箱和拆箱
装箱,将基本数据类型转换成包装器类型。拆箱,将包装器类型转换成基本数据类型,拆箱和装箱是编译器自动实现转换。
1,定义一个Integer类型赋值。
Integer a = 100;//装箱
int b = a;//拆箱
基本类型赋值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);
}
-128~127范围,使用缓存Integer对象,对于该范围int的相同基本数字装箱的Integer是同一地址对象。
其他范围创建一个Integer对象,内部value赋值。
将Integer类型赋值基本类型,自动拆箱,该过程调用Integer类intValue()方法。
public int intValue() {
return value;
}
返回内部int类型value数据,赋值给int基本变量类型。
2,Integer类型列表添加元素。
List<Integer> list = new ArrayList<>();
list.add(10);//装箱
int value = list.get(0);//拆箱
List的add()方法,添加一个基本类型,自动装箱,从List中获取一个元素(Integer),赋值给基本int类型,自动拆箱。
3,Integer类型Map添加元素。
HashMap<Integer,String> map = new HashMap<>(Integer,String);
map.put(10, "test");//装箱
map.get(10);//拆箱
HashMap的key是Integer类型,put()方法和get()方法,添加/获取kv,基本类型参数key自动装箱,new创建对象,频繁装箱影响内存和性能。
4,反编译,初始化a和b变量代码,通过javap反编译查看。
public static void main(java.lang.String[]);
Code:
0: bipush 100
2: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: aload_1
7: invokevirtual #22 // Method java/lang/Integer.intValue:()I
10: istore_2
11: return
LineNumberTable:
line 8: 0
line 9: 6
line 10: 11
LocalVariableTable:
Start Length Slot Name Signature
0 12 0 args [Ljava/lang/String;
6 6 1 a Ljava/lang/Integer;
11 1 2 b I
编译class字节码,invokestatic,Integer类的valueOf()和intValue()方法,自动装箱和拆箱。
三、运算
int a = 120;
Integer b = 120;
System.out.println(a == b);//true
Integer c = 120;
Integer d = 120;
System.out.println(c == d);//true
c = 200;
d = 200;
System.out.println(c == d);//false
Double e = 10.0;
Double f = 10.0;
System.out.println(e == f);//false
1,基本类型和包装器类型运算时,按基本类型,b是Integer类型,赋值时自动装箱,和int基本类型比较,b自动拆箱。
2,c和d都是Integer类型,(==比较内存地址),赋值基本类型,装箱,值在-128~127范围,Integer缓存对象,数值相同,自动装箱对象是同一个,地址相同。
3,c和d赋值基本类型,大于127范围,分别new装箱对象,地址不同。
4,Double类赋值基本类型时,自动装箱,==比较地址,装箱调用valueOf()方法。
public static Double valueOf(double d) {
return new Double(d);
}
创建Double对象,未使用缓存,所以两个new对象==地址不等,(与Integer类不同)。
四、总结
当一个包装类和基本数据类型运算(==、+、-、*、/、>、<)时,将包装类进行拆箱,按照基本类型进行运算。
赋值运算时,根据变量类型(基本类型和包装类类型),自动装箱或拆箱。
equals()比较时,装箱操作。
装箱,创建对象。
任重而道远
网友评论