1. 基本数据类型及其封装类
基本类型 | 大小(字节) | 默认值 | 封装类 |
---|---|---|---|
byte | 1 | (byte)0 | Byte |
short | 2 | (short)0 | Short |
int | 4 | 0 | Integer |
long | 8 | 0L | Long |
float | 4 | 0.0f | Float |
double | 8 | 0.0d | Double |
boolean | - | false | Boolean |
char | 2 | \u0000(null) | Character |
注意:
- boolean单独使用是占4个字节,在数组中又是1个字节。
- 基本类型放在栈中,直接存储值。
- 所有数值类型都有正负号,没有无符号的数值类型。
2. 装箱、拆箱
- 装箱就是将基本数据类型转换为封装类;
- 拆箱就是将封装类转换为基本数据类型;
JDK5 后提供了自动装箱和拆箱的功能,此功能事实上是编译器来帮忙,编译器在编译时依照编写的方法,决定是否进行装箱或拆箱动作。
- 自动装箱时,编译器调用
valueOf(int k)
将原始类型值转换成对象 - 自动拆箱时,编译器通过调用类似
intValue()
这类的方法将对象转换成原始类型值。
举例如下:
int a = 10;
Integer b = new Integer(a);// 手动装箱
Integer c = a; // 自动装箱
int d = b.intValue(); // 手动拆箱
int f = b; // 自动拆箱
3. IntegerCache类
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
查阅JDK的源码,可以发现 Java 为了提高效率,使用了 IntegerCache
这个类。IntegerCache 类中有一个数组 cache
,里面缓存了值从 -128 到 127 的 Integer 对象。
当我们调用 Integer.valueOf(int i)
的时候,如果
i
i
i 的值是在
[
−
128
,
127
]
[-128,127]
[−128,127] 之间时,会直接从这个缓存数组中返回一个对象,否则就 new 一个 Integer 对象。
4. 比较
- 封装类型 == 基本类型:封装类型先拆箱为基本类型,再进行数值上的比较。
- 封装类型.equals(基本类型):基本类型先装箱为包装类型,如果基本类型不为空且数值和封装类型相同,则返回true。
- 封装类型.equals(封装类型):先进行类型比较,类型相同的情况下,再比较值,如果值也相同,则返回true。
- 封装类型==封装类型:Integer值如果在
-128~127
,则返回true,这和Integer.valueOf()
的缓冲对象有关,否则返回false;
5. 相关问题
1、为什么需要封装类,只有基本类型不行吗?
因为泛型类包括预定义的集合,使用的参数都是对象类型,无法直接使用基本数据类型,所以Java又提供了这些基本类型的封装。
2、基本类型和对应的封装类由于本质的不同,具有哪些区别?
- 基本类型只能按值传递,而封装类按引用传递。
- 基本类型会在栈中创建,而对于对象类型,对象在堆中创建,对象的引用在栈中创建,基本类型由于在栈中,效率会比较高,但是可能存在内存泄漏的问题。
3、看代码回答问题
public static void main(String[] args) {
int a = 100;
Integer b = 100;
System.out.println(a==b);
}
(1)a == b
编译能通过吗?
答:能。
(2)== 比较用的是拆箱还是装箱?
答:拆箱。
(3)拆箱用的什么方法?
答:调用 Integer 类的 intValue()
方法。
(4)结果输出什么?
答:true。
(5)如果a和b都改为1000,结果会输出什么?
答:true。因为 == 比较用的是拆箱,所以比较时是数值上的比较。
4、为什么缓存范围是 -128 到 127?
大概是因为这个范围的数值使用频率比较高吧,我也不知道为啥。
5、看代码判断输出结果
public static void main(String[] args) {
//1
Integer a=new Integer(123);
Integer b=new Integer(123);
System.out.println(a==b);//输出 false
//2
Integer c=123;
Integer d=123;
System.out.println(c==d);//输出 true
//3
Integer e=129;
Integer f=129;
System.out.println(e==f);//输出 false
//4
int g=59;
Integer h=new Integer(59);
System.out.println(g==h);//输出 true
}