目录
一. Java基本类型与包装类型介绍
Java中有8种基本数据类型,分别为:
- 数字类型(6种) :byte、short、int、long、float、double
- 字符类型(1种) :char
- 布尔型(1种) :boolean。
这八种基本类型都有对应的包装类分别为:
- Byte、Short、Integer、Long、Float、Double
- Character
- Boolean
基本类型 | 位数 | 字节 | 默认值 |
---|---|---|---|
int | 32 | 4 | 0 |
short | 16 | 2 | 0 |
long | 64 | 8 | 0L |
byte | 8 | 1 | 0 |
char | 16 | 2 | 'u0000' |
float | 32 | 4 | 0f |
double | 64 | 8 | 0d |
boolean | 1 | 官方文档未明确定义,它依赖于 JVM 厂商的具体实现。逻辑上理解是占用 1位,但是实际中会考虑计算机高效存储因素。 | false |
二 类型的自动装箱与拆箱
装箱与拆箱的含义:
- 装箱:将基本类型用它们对应的引用类型包装起来;
- 拆箱:将包装类型转换为基本数据类型;
Java基本类型的包装类的大部分实现了常量池技术,即Byte,Short,Integer,Long,Character,Boolean;前面4种包装类默认创建了数值[-128,127]
的相应类型的缓存数据,Character创建了数值在[0,127]
范围的缓存数据,Boolean 直接返回True Or False。如果超出对应范围仍然会去创建新的对象。其中仅浮点数类型的包装类Float
与Double
没有实现常量池技术。
Boolean常量池
public static Boolean valueOf(boolean b) {
return (b ? TRUE : FALSE); // 其中TRUE与FALSE为定义的静态常量
}
CharacterCache 缓存常量池
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);
}
}
/**
*此方法将始终缓存-128 到 127(包括端点)范围内的值,并可以缓存此范围之外的其他值。
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high) //如果在缓存范围值内
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i); // 不如不在范围内者使用new运算符创建一个堆内存返回新的对象
}
举例说明
例子1
Integer i1 = 33;
Integer i2 = 33;
System.out.println(i1 == i2);// 输出 true, 因为33在-128-127范围内使用的是缓存常量,即两个数值的内存地址一致
Integer i11 = 333;
Integer i22 = 333;
System.out.println(i11 == i22);// 输出 false // 超出范围,返回的都是new的新对象
Double i3 = 1.2;
Double i4 = 1.2;
System.out.println(i3 == i4);// 输出 false // Double未实现缓存常量池
例子2
需要注意一旦使用new
运算符创建对象,则将创建新的数据,不会使用缓存常量值,如以下
Integer i1 = 40;
Integer i2 = new Integer(40);
System.out.println(i1==i2);//输出 false
- Integer i1=40;Java 在编译的时候会直接将代码封装成 Integer i1=Integer.valueOf(40);,从而使用常量池中的对象。
- Integer i1 = new Integer(40);这种情况下会创建新的对象。
例子3
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
System.out.println("i1=i2 : " + (i1 == i2)); // true,两个变量使用的是同一个常量值
System.out.println("i1=i2+i3 : " + (i1 == i2 + i3)); // true, 因为"+"加号运算符不能使用在Integer上,所以会自动拆箱为基础类型int:40+0=40, 同时"="等号也无法使用在Integer上,则最终比较为40=40
System.out.println("i1=i4 : " + (i1 == i4));// false
System.out.println("i4=i5 : " + (i4 == i5)); // false
System.out.println("i4=i5+i6 : " + (i4 == i5 + i6)); //true,加法运算发自动拆箱后进行加法运行并进行比较
System.out.println("40=i5+i6 : " + (40 == i5 + i6));// true,加法运算发自动拆箱后进行加法运行并进行比较
评论 (0)