基本数据类型和包装类

Java八种基本数据类型分为四类八种,四类分别为整型、浮点型、布尔型、字符型;八种分别为byte、short、int、long、float、double、boolean、char;

基本数据类型 包装类 字节数 位数 范围 默认值
整形 byte Byte 1 8 -127,128 0
sort Sort 2 16 -2^15,2^15-1 0
int Integer 4 32 -2^31,2^31-1 0
long Long 8 64 -2^63,2^63-1 0L
浮点型 float Float 4 32 0.0f
double Double 8 64 0.0d
布尔型 boolean Boolean 1 8 true,false true
字符型 char Character 2 16 一个字符 '\u0000'转化为int为0

为什么需要基本数据类型

Java是一门面向对象的语言,万事万物都是对象。在Java中我们需要new来创建一个对象,这个对象会储存在堆里,通过栈中的引用指向这些对象。但是对于这些我们经常使用的数据类型这样的做法不是很高效,所以Java引入了基本数据类型将这些变量直接保存在栈中。

为什么需要包装类

基本数据类型不属于类,它们没有类的性质。为了让基本数据类型拥有类的性质,Java为每一个基本数据类型提供了它们的包装类,使得它们有类的性质。这些包装类提供了许多属性和方法,丰富了基本数据类型的操作,使得程序员使用更方便,开发更高效。

装箱与拆箱

  1. 自动装箱 基本数据类型——>包装类(原理是调用了valueOf方法)
  2. 自动拆箱 包装类——>基本数据类型 (原理是调用了xxxValue方法)
1
2
3
4
5
//装箱
Integer i1 = new Integer(10); //jdk1.5之前
Integer i2= 10; //jdk1.5之后
//拆箱
int n = i;

Integer的valueOf方法的具体实现

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
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() {}
}

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

从这段代码可以看出,在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

下面是一个例子

1
2
3
4
5
6
7
8
9
10
11
public class Test1 {
public static void main(String[] args) {
Integer i1 = 50;
Integer i2 = 50;
Integer i3 = 250;
Integer i4 = 250;

System.out.println(i1==i2);
System.out.println(i3==i4);
}
}

输出结果为

1
2
true
false

上面的代码中i1和i2的数值为50,小于缓存大小,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

Integer的intValue方法的具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;

/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}

public int intValue() {
return value;
}

Integer类中value属性存放了Integer对象的值,intValue方法直接返回value的值就可以了。

Boolean的valueOf方法的具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* The {@code Boolean} object corresponding to the primitive
* value {@code true}.
*/
public static final Boolean TRUE = new Boolean(true);

/**
* The {@code Boolean} object corresponding to the primitive
* value {@code false}.
*/
public static final Boolean FALSE = new Boolean(false);

public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE);
}

下面有个例子

1
2
3
4
5
6
7
8
9
10
11
public class Test1 {
public static void main(String[] args) {
Boolean b1 = false;
Boolean b2 = false;
Boolean b3 = true;
Boolean b4 = true;

System.out.println(b1==b2);
System.out.println(b3==b4);
}
}

输出结果为

1
2
true
true

布尔型在装箱时调用valueOf方法返回的都是一个Boolean对象的索引。

Boolean的booleanValue方法的具体实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* The value of the Boolean.
*
* @serial
*/
private final boolean value;

public Boolean(boolean value) {
this.value = value;
}

public boolean booleanValue() {
return value;
}

通过查看其它类的该方法的源码之后,可以得到该表:

包装类 vauleof
Byte 缓存(-128,127),且byte值的范围也是(-128,127)
Short 缓存(-128,127)
Integer 缓存(-128,127)
Long 缓存(-128,127)
Float 没有缓存,new一个对象
Double 没有缓存,new一个对象
Boolean 直接返回,不new
Character 缓存(0,127)