Java的八大基本类型:
基本数据类型的自动提升:
实线表示自动转换时不会造成数据丢失,虚线则可能会出现数据丢失问题。
基本数据类型共有8种,分别是:布尔型boolean, 字符型char和数值型byte/short/int/long/float/double。由于字符型char所表示的单个字符与Ascii码中相应整形对应,因此,有时也将其划分到数值型中。
注意:
- char可以看成数值类型,但是char是无符号类型,数据范围为0~2^16-1。其他数值类型是有符号类型,因此其他数据类型转char时要特别注意符号问题。
- 另外,向下转换时可以直接将 int 常量字面量赋值给 byte、short、char 等数据类型,而不需要强制转换,只要该常量值不超过该类型的表示范围都能自动转换。
- 从存储范围小的类型到存储范围大的类型:
从低到高:byte ->short(char)->int->long->float->double - byte/short/int/long/float/double的最高位都是符号位。float中第1位是符号位,2-9位是指数位,10-32为是数据位。double中第1位是符号位,2-12位是指数位,13-64为是数据位。因此当long转float或double和int转float时,因数据位不够,可能会造成数据丢失。而int转double时因数据位足够,因此不会有数据丢失。
- boolean类型无法和其他基本类型作转换
Java中整型数值默认是int类型,小数数值默认是double类型。
double a = 3.14; //3.14默认是double类型
double b = 3; //int类型的3自动向上转为double(无数据丢失)
float c = 3.14; //报错:3.14为double类型,double向下转型float会造成数据丢失
float d = 3.14F; //两种正确写法:显示转型
float e = (float) 3.14
long f = 10000000000; //报错:一百亿这个数超过了int的范围,应该转为long类型
long e = 10000000000L; //显式转型
不同数据类型作运算时:
不同数据类型作运算时,先要将两个操作数转换为同一种类型,然后再进行计算。
引用《Java核心技术卷I》的原话:
如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型。
否则,如果其中一个操作数是float类型,另一个操作数就会转换为float类型。
否则,如果其中有一个操作数是long类型,另一个操作数就会转换为long类型。
否则,两个操作数都将被转换为int类型。
//例1:
byte b1 = 2, b2 = 4;
short s = 16;
b2 = s; //报错:short类向下转为byte时要显示强制转型( a2=(btye)s; ),可能会数据丢失
b1 = b1 * b2; //报错:a1,a2转为int类型再作运算,运算结果也为int,需要强制转型为byte再赋值给b1
b1++;
b1 *= b2; //但是自增自减运算符和赋值运算符没有自动转型的问题,会自动转型
//例2:
int x = 1;
float y = 2; //int类型的2,自动隐式的转为float
System.out.println(x/y); //输出结果为 0.5。最高精度为float,因此x会先向上转为float再运算,结果为float类型的0.5
//例3:
byte a = 100, b;
b = (byte) (a * 1 + 28); //a先自动转为int类型再作运算,运算结果为int类型的128,再转为byte类型赋值给b.而128显然超过了byte类型的范围
System.out.println(b); //结果为 -128
解释:
- java中如果碰到char、byte和short参与运算时,会自动将这些值转换为int类型然后再进行运算。
- 当多个精度的数字同时进行运算时,最终结果以最高精度为准。
- a*1+28的计算结果为int类型的128,二进制补码为0000,0000,0000,0000,0000,0000,1000,0000。byte类型只有1个字节,强转时只取了最低的1个字节数据,因此byte变量最后得到的补码为1000,0000,也就是二进制原码的 -128。