书接上回 Java 变量介绍 我们继续学习以下内容.
- 四、常量
- 字面值常量
- final 关键字修饰的常量
- 五、理解类型转换
- int 和 long/double 相互赋值
- int 和 boolean 相互赋值
- int 字面值常量给 byte 赋值
- 强制类型转换
- 类型转换小结
- 六、理解数值提升
- int 和 long 混合运算
- byte 和 byte 的运算
- 类型提升小结
- 七、int 和 String 之间的相互转换
- int 转成 String
- String 转成 int
- 八、总结
四、常量
上面讨论的都是各种规则的变量,每种类型的变量也对应着一种相同类型的常量。
常量指的是运行时类型不能发生改变。
常量主要有以下两种体现方式:
字面值常量
10 // int 字面值常量(十进制)
010 // int 字面值常量(八进制)由数字0开头. 010就是十进制的8
0x10 // int 字面值常量(十六进制)由数字0x开头. 0x10就是十进制的16
10L // long 字面值常量. 也可以写作 10l(小写的L)
1.0 // double 字面值常量 也可以写作 1.0d 或者 1.0D
1.5e2 // double 字面值常量 科学计数法表示 相当于 1.5*10^2
1.0f // float 字面值常量,也可以写作 1.0F
true // boolean 字面值常量,同样还有 false
'a' // char 字面值常量,单引号中只能有一个字符
"abc" // String 字面值常量,双引号中可以有多个字符
final 关键字修饰的常量
final int a = 10;
a = 20; //编译出错,无法为最终变量 a 分配值
常量不能在程序运行过程中发生修改
五、理解类型转换
Java 作为一个强类型编程语言,当不同类型之间的变量相互赋值的时候,会有严格的校验。
先看以下几个代码场景:
int 和 long/double 相互赋值
int a = 10;
long b = 20;
a = b; //编译出错,提示可能会损失精度.
b = a; //编译通过.
int a = 10;
double b = 1.0;
a = b; //编译出错,提示可能会损失精度.
b = a; //编译通过.
long 表示的范围更大,可以将 int 赋值给 long,但是不能将 long 赋值给 int.
double 表示的范围更大,可以将 int 赋值给 double,但是不能将 double 赋值给 int.
结论:
不同数字类型的变量之间赋值,表示范围更小的类型能隐式转换成范围较大的类型,反之则不行。
就相当于两杯水,int类型的水杯小,long类型的水杯大。
小水杯可以把水装进大水杯,而大水杯不能把水装进小水杯。
int 和 boolean 相互赋值
int a = 10;
boolean b = true;
b = a; //编译出错,提示不兼容的类型
a = b; //编译出错,提示不兼容的类型
结论:int 和 boolean 是两种毫不相干的类型,不能相互赋值。
int 字面值常量给 byte 赋值
byte a = 100; //编译通过
byte b = 256; //编译报错,提示从 int 转换到 byte 可能会有损失
注意:byte 表示的数据范围是 -128~+127已经超出范围,而 100 还在范围之内.
结论:使用字面值常量赋值的时候,Java 会自动进行一些检查校验,判断赋值是否合理.
强制类型转换
int a = 0;
double b = 10.5;
a = (int)b;
int a = 10;
boolean b = false;
b = (boolean)a; //编译出错,提示不兼容的类型.
结论:使用 “(类型)” 的方法可以将 double 类型强制转成 int,但是
- 强制类型转换,可能会导致精度丢失,例如强制转换后,10.5 就变成 10 了,小数点后面的部分被忽略。
- 强制类型转换不一定会成功,互不相干的类型之间无法强转。
类型转换小结
- 不同数字类型的变量之间赋值,表示范围更小的类型能隐式转换成范围较大的类型.
- 如果需要把范围大的类型赋值给范围小的,需要强制类型转换,但是可能会精度丢失.
- 将一个字面值常量进行赋值的时候,Java 会自动针对数字范围进行检查.
六、理解数值提升
int 和 long 混合运算
int a = 10;
long b = 20;
int c = a + b; //编译出错,提示将 long 转成 int 会丢失精度.
long d = a + b; //编译通过.
结论:当 int 和 long 混合运算的时候,int 会提升成 long,得到的结果仍然是 long 类型,需要使用 long 类型的变量来接收结果。如果非要用 int 来接收数据,就需要使用强制类型转换。
byte 和 byte 的运算
public static void main(String[] args) {
byte a = 10;
byte b = 20;
byte c = a + b; //编译出错!
}
结论:
虽然 byte 和 byte 都是相同类型,但是出现编译错误,计算 a+b 会先将 a 和 b 都提升成 int,再进行计算,得到的结果也是 int,最后赋值给 c,导致出现上述错误.
为什么会偷偷的提升类型?
由于计算机的 CPU 通常是按照 4 个字节为单位从内存中读写数据。为了硬件上实现方便,byte 和 short 这种低于 4 个字节的类型,会先提升到 int,再参与计算。
so 正确的写法:
byte a = 10;
byte b = 20;
byte c = (byte)(a + b);
类型提升小结
- 不同类型的数据混合运算,范围小的会提升成范围大的.
- 对于 short、byte 这种比 4 个字节小的类型,会先提升成 4 个字节的 int,再运算。
七、int 和 String 之间的相互转换
int 转成 String
int num = 10;
//方法一
String str1 = num + "";
//方法二
String str2 = String.valueOf(num);
String 转成 int
String str = "100";
int num = Integer.parseInt(str);
八、总结
Java 类型汇总,前面的内容重点介绍的都是基本数据类型.
每种数据类型及其范围,都是我们需要掌握的重点。
难点是隐式类型转换和类型提升,我们只要在代码中避免不同类型混用的情况,就能减少出现隐式转换和类型提升。