1.8种基本类型
- 上图可以看出Java的数据类型分为基本数据类型和引用数据类型,下面介绍8种基本数据类型。
1.1.整数类型
| 类型 | 占用空间 | 范围 |
|---|---|---|
| byte(字节) | 1字节 | -128~127 |
| short(短整型) | 2字节 | -2^15~2^15-1 |
| int(整型) | 4字节 | -2^31~2^31-1 |
| long(长整型) | 8字节 | -2^63~2^63-1 |
- 整数类型使用细节:
Java声明的整型常量默认为int型,声明long型常量的话必须在后面加 "l"或"L"
1.2.浮点类型
| 类型 | 占用空间 | 范围 |
|---|---|---|
| float(单精度) | 4字节 | -3.403E38~3.403E38 |
| double(双精度) | 8字节 | -1.798E308~1.798E308 |
-
浮点类型使用细节:
- 浮点数在机器中的存放形式:符号位+指数位+尾数位
- 尾数部分可能丢失,造成精度损失(小数都是近似值)
- Java声明的浮点类型默认为double型,声明float型常量须在后面加 "f"或"F"
float f = 1.1;//错误
float f1 = 1.1f;//正确
double d = 1.1f;//正确
-
浮点型常量有两种表示形式:
-
十进制:
double d = 0.23/0.23f/.23; -
科学计数法
-
double d4 = 1.23e2;//相当于123.0
System.out.println("d4 = "+ d4);
通常情况下推荐使用double,因为它比float 更精确**
double d5 = 1.23456789;
float f2 = 1.23456789f;
System.out.println("d5 = "+ d5);
System.out.println("f2 = "+ f2);
- 浮点类型使用陷阱
double d6 = 2.1 / 3;//认为是0.7
System.out.println(d6);//输出的是一个近似0.7的小数
double d7 = 0.7;
System.out.println(d6 == d7);//false
原因:计算机在存储小数时会有精度的误差
总结出:在对运算结果是小数的量进行判断时,不能直接判断可能有误差,建议的方法是以两个数的差值的绝对值在某个精度内进行判断
if (Math.abs(d6 - d7) < 0.0000001){
System.out.println("可以认为两数相等");
}
1.3.字符类型
| 类型 | 占用空间 | 范围 |
|---|---|---|
| char | 2字节 | 0~2^16-1 |
char,存放单个字符
-
使用细节
- 字符类型也可以直接存放一个整数,输出时会输出unicode码对应字符
char a = 97;
System.out.println(a);
- char的本质是一个整数,在输出时输出对应unicode码对应的字符
- char可以进行运算,值相当于字符对应的unicode码
1.4.布尔类型
| 类型 | 占用空间 | 范围 |
|---|---|---|
| boolean | 1字节或4字节 | true/false |
- boolean类型只允许取值true和false,没有null
- 不可以用0和非0的整数代替true和false
1.5.基本类型数据转换
- 自动类型转换
在进行运算时,精度小的类型自动转化为精度大的类型,转换排序如下图
- (byte、short)和char 不会相互自动转换
- byte、short 和 char 参与运算时,当作 int 类型处理
- 自动提升原则:表达式结果的类型会自动提升为操作数中最大的类型
-
强制类型转换
- 自动类型转换的逆过程,使用时要加上强制转换符 (),可能造成精度损失或溢出
- 强转符号只对最近的操作数有效,多使用小括号提升优先级
int x = (int)2.5*2;
int y = (int)(2.5*2);
System.out.println(x+"\t"+y);
- char类型在保存int的变量值时需要强转
int i = 100;
char c = i;//错误
char c1 = (int)i;//正确
2.包装类
2.1.包装类的分类
- 针对八种基本数据类型有相应的引用类型—包装类,有了类的特点,就可以调用类中的方法
| 基本数据类型 | 包装类 |
|---|---|
| boolean | Boolean |
| char | Character |
| byte | Byte |
| short | Short |
| int | Integer |
| long | Long |
| float | Float |
| double | Double |
- 高亮部分的包装类父类都是:Number
- 8中包装类的继承关系图
- Byte、Short、Integer、Long、Float和Double都是Number的子类,且都实现了Comparable接口。
- Boolean、Character这两个是单独的类,都实现了Serializable和Comparable接口。
2.2.装箱和拆箱
- 装箱:基本类型→包装类型,反之即为拆箱
- jdk5以前是手动装箱和拆箱(以 int 和 Integer 为例)
//jdk5以前是手动装箱和拆箱
//手动装箱 以 int → Integer 为例
int n1 = 100;
Integer integer = new Integer(n1);
Integer integer1 = Integer.valueOf(n1);
//手动拆箱
int n2 = integer.intValue();
System.out.println("integer = "+ integer);
System.out.println("integer1 = "+ integer1);
System.out.println("n2 = "+ n2);
- jdk5以后是自动装箱拆箱(以int 和 integer 为例)
//jdk5以后是自动装箱和拆箱
//自动装箱
int n3 = 200;
Integer integer = n3;
//自动拆箱
int n4 = integer;
System.out.println("n3 = "+ n3);
System.out.println("ineger = "+ integer);
- 通过debug可以看到,自动装箱在底层仍然使用的是 Integer.valueOf() 方法
- 自动拆箱在底层仍然使用的是 .intValue() 方法
- 八种类型都可以同样地装箱和拆箱
2.3.包装类和String类的相互转换
- 包装类以Integer为例,其他类似
//包装类(Integer)→ String
Integer i = 100;//自动装箱
//方式1
String s1 = i + "";
//方式2
String s2 = i.toString();
//方式3
String s3 = String.valueOf(i);
System.out.println("s1 = "+ s1);
System.out.println("s2 = "+ s2);
System.out.println("s3 = "+ s3);
//String → 包装类(Integer)
//方式1
Integer n1 = Integer.valueOf(s3);
//方式2
Integer n2 = new Integer(s3);
System.out.println("n1 = "+ n1);
System.out.println("n2 = "+ n2);
2.4.Integer缓存
- Integer内部定义了IntegerCache结构,其中定义了数组Integer[],缓存了-128~127范围的整数,在自动装箱时此范围内的整数可以直接使用数组内的元素,不再new新的对象。这种方法可以提高效率。
Integer int1 = 127;
Integer int2 = 127;
System.out.println(int1 == int2);//输出true
Integer int3 = 128;
Integer int4 = 128;
System.out.println(int3 == int4);//输出false