# Java 基本数据类型
Java提供了八种基本类型。六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型。
- 整数型: byte、short、int、long
- 浮点型:float、double
- 字符类型:char
- 布尔类型:boolean
这八种基本类型都有对应的包装类分别为:Byte
、Short
、Integer
、Long
、Float
、Double
、Character
、Boolean
# 包装类型的缓存源码
- Integer 缓存源码
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 final Integer cache[];
static {
// high value may be configured by property
int h = 127;
// ...
}
private IntegerCache() {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- Boolean 缓存源码
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}
1
2
3
2
3
- Character 缓存源码
public static Character valueOf(char c) {
if (c <= 127) { // must cache
return CharacterCache.cache[(int)c];
}
return new Character(c);
}
private static class CharacterCache {
private CharacterCache(){}
static final Character cache[] = new Character[127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Character((char)i);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
包装类型Byte
,Short
,Integer
,Long
这4
种包装类默认创建了数值 [-128,127]
的相应类型的缓存数据,
Character
创建了数值在 [0,127]
范围的缓存数据,Boolean
直接返回 True
or False
。
而两种浮点数类型的包装类 Float
,Double
并没有实现缓存机制。
# 自动装箱与拆箱
- 装箱:将基本类型用它们对应的引用类型包装起来;
- 拆箱:将包装类型转换为基本数据类型;
例:
Integer i = 10; //装箱 等价于 Integer i = Integer.valueOf(10)
int n = i; //拆箱 等价于 int n = i.intValue();
1
2
2
装箱其实就是调用包装类的valueOf()
方法,拆箱其实就是调用了xxxValue()
方法。
注意:如果频繁拆装箱的话,也会严重影响系统的性能。我们应该尽量避免不必要的拆装箱操作
# == 与 equals的区别
==
的作用是判断两个对象的地址是不是相等。即判断两个对象是不是同一个对象。(基本数据类型==
比较的是值,引用数据类型==
比较的是内存地址)equals()
的作用也是判断两个对象是否相等。但它一般有两种使用情况- 类没有覆盖
equals()
方法,则通过equals()
比较该类的两个对象时,等价于通过==
比较这两个对象(属于object
类,默认是判断内存地址是否相同); - 类可以重写
equals()
方法,具体判断对象是否相等是根据程序而定的,如在String
类中只是比较对象内容是否一致。
- 类没有覆盖
# 【易错点】 整型包装类对象之间值的比较
/**
* 1. i1,i2 都会发生装箱操作,实际上他们都等同于 Integer.valueOf(100)
* 2. Integer 的缓存机制会把创建数值 [-128,127] 的相应类型的缓存数据
* 3. 因为 100 在 [-128,127] 范围之类,获取到的对象是一样的,所以输出true
*/
Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 == i2);// 输出 true
/**
* 1. i3,i4 都会发生装箱操作,实际上他们都等同于 Integer.valueOf(100)
* 2. Integer 的缓存机制会把创建数值 [-128,127] 的相应类型的缓存数据
* 3. 因为 1000 不在 [-128,127] 范围之类,则实际上 i3 = new Integer(1000)、i4 = new Integer(1000),创建了两个新的对象,对象的地址肯定不相同,所以输出false
*/
Integer i3 = 1000;
Integer i4 = 1000;
System.out.println(i3 == i4);// 输出 false
/**
* 1. i5 会发生装箱操作,实际上他们都等同于 Integer.valueOf(100)
* 2. i6 会直接创建新的对象,对象的地址肯定不相同,所以输出false
*/
Integer i5 = 100;
Integer i6 = new Integer(100);
System.out.println(i5 == i6); // 输出 false
/**
* 1. 两种浮点数类型的包装类 Float,Double 并没有实现缓存机制
* 2. f1,f2,d1,d2 都发生了装箱操作,创建了新的对象,对象的地址肯定不相同,所以输出false
*/
Float f1 = 33f;
Float f2 = 33f;
System.out.println(f1 == f2);// 输出 false
Double d1 = 1.2;
Double d2 = 1.2;
System.out.println(d1 == d2);// 输出 false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
阿里云JAVA开发手册 OOP 规约
- 【强制】所有整型包装类对象之间值的比较,全部使用 equals 方法比较。 说明:对于 Integer var = ? 在-128 至 127 之间的赋值,Integer 对象是在 IntegerCache.cache 产生, 会复用已有对象,这个区间内的 Integer 值可以直接使用==进行判断,但是这个区间之外的所有数据,都 会在堆上产生,并不会复用已有对象,这是一个大坑,推荐使用 equals 方法进行判断。