- 1、基本数据类型
- 2、包装类
- 3、自动装箱和自动拆箱
- (1)自动装箱
- (2)自动拆箱
- (3)什么时候发生自动装拆箱
- 4、常量池
- (1)基本数据常量池
- (2)用Integer i = 创建对象
- (3)用new Integer()创建对象
- (4)具体示例
在介绍自动装箱和自动拆箱之前,我们要先了解概念:基本数据类型、包装类和常量池。
1、基本数据类型Java基本数据类型:有8种,分别是byte(字节)、short(短整型)、int(整型)、long(长整型)、float(浮点型)、double(双精度浮点型)、boolean(布尔类型)、char(字符型)。
基本数据类型 | 字节 | 位数 | 取值范围 | 默认值 |
---|---|---|---|---|
byte | 1 | 8 | -128~127 | 0 |
short | 2 | 16 | -32768 ~ 32767 | 0 |
int | 4 | 32 | -2147483648 ~ 2147483647 | 0 |
long | 8 | 64 | -9223372036854775808 ~ 9223372036854775807 | 0L |
float | 4 | 32 | 1.4E-45 ~ 3.4028235E38 | 0f |
double | 8 | 64 | 4.9E-324 ~ 1.7976931348623157E308 | 0d |
boolean | 1 | —— | true、false | false |
char | 2 | 16 | 0 ~ 65535 | ‘u0000’ |
包装类:作为面向对象语言,有些情况下不能直接对基本数据类型的数据进行处理,为了使基本类型可以像对象一样 *** 作,所以Java语言将基本数据类型包装起来,形成了对应的包装类,对应关系如下表。
基本数据类型 | 对应包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
那么,这两种类型如何转换呢?Java的自动装箱和自动拆箱机制实现了基本数据类型与包装类型的自动转换,在使用到的时候,无需我们人工进行转换 *** 作。
(1)自动装箱Java自动将基本数据类型转换为包装类型,也就是int→Integer,实际上是调用了方法Integer.valueOf(int)。
public static void main (String[] args) {
// 创建Integer类型的对象i1时,我们可以直接写60(基本数据类型)
// 这时会发生自动装箱,将基本数据类型转换为Integer
// 相当于 Integer i1 = Integer.valueOf(i1);
Integer i1 = 60;
}
(2)自动拆箱
Java自动将包装类型转换为基本数据类型,也就是Integer→int,实际上是调用了方法Integer.intValue()。
(3)什么时候发生自动装拆箱① 赋值 *** 作:在包装类型和基本数据类型之间进行赋值 *** 作时,会发生自动拆装箱。
public static void main (String[] args) {
// i1是Integer包装类型
Integer i1 = 10;
// i2是基本数据类型
int i2 = 20;
// 进行赋值时,会发生自动拆箱
i1 = i2;
System.out.println(i1);
}
②比较:在包装类型与基本数据类型进行比较时,会先将包装类进行拆箱成基本数据类型(Integer→int),然后再进行比较。
public static void main (String[] args) {
// i1是Integer包装类型
Integer i1 = 10;
// i2是基本数据类型
int i2 = 20;
// 进行比较时,会发生自动拆箱,将Integer转换成int
if (i1 < i2)
System.out.println("i1 小于 i2");
}
③运算符: *** 作符的只能对基本数据类型进行运算,所以在包装类和基本数据类型进行运算时,会发生自动拆箱,将包装类型转换成基本数据类型进行运算。
public static void main (String[] args) {
// i1是Integer包装类型
Integer i1 = 10;
// i2是基本数据类型
int i2 = 20;
// 进行 *** 作符运算时时,会发生自动拆箱
int i3 = i1 + i2;
System.out.println(i3);
}
④方法传参:有时候我们的方法形参是包装类型,传入基本数据类型时,会发生自动装箱;形参是基本数据类型,传入包装类型时,会发生自动装箱。
// 自动拆箱
public static int getNum1 (Integer a) {
return a;
}
// 自动装箱
public static Integer getNum2 (int b) {
return b;
}
4、常量池
(1)基本数据常量池
Java为大部分基本类型(6种)的包装类(Byte、Short、Integer、Long、Boolean、Character)实现了常量池技术,为它们创建了[-128,127]范围内的缓存数据,具体范围见下表所示。
包装类 | 常量池范围 |
---|---|
Byte | -128 ~ 127(所有) |
Short | -128 ~ 127 |
Integer | -128 ~ 127 |
Long | -128 ~ 127 |
Character | ‘\u0000’ ~ ‘\u007F’ |
Boolean | true和 false |
当我们用Integer i = xxx创建对象时,会发生自动装箱,调用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);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static {
// high value may be configured by property
int h = 127;
}
}
这时:
①如果数据大小在缓存数据范围内,那么会直接使用获取常量池中已经创建好的数据;
②如果不在缓存数据范围内,则会用new Integer(xxx)在堆中创建新的对象。
注:Float、Double并没有实现缓存池技术,这是因为浮点型数据有小数,数据个数是不可数的,没办法提前创建。
当我们用new Integer()创建Integer对象时,无论数据大小是多少,都会在堆中新建一个对象。
(4)具体示例public static void main (String[] args) {
Integer i1 = 10;
Integer i2 = 10;
Integer i3 = new Integer(10);
int i4 = 10;
int i5 = 200;
Integer i6 = 200;
Integer i7 = 200;
Integer i8 = new Integer(200);
System.out.println(i1 == i2); // true
System.out.println(i1 == i3); // false
System.out.println(i1 == i4); // true
System.out.println(i2 == i3); // false
System.out.println(i5 == i6); // true
System.out.println(i5 == i7); // true
System.out.println(i5 == i8); // true
System.out.println(i6 == i7); // false
System.out.println(i7 == i8); // false
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)