在了解数据类型转换之前,先回忆,java的基本的数据类型,有8种,除了布尔之外,其余的7种经常遇到不同类型的转换问题!
还有就是布尔型的,java规范强烈的不建议布尔型和整型或者浮点型的进行转化,很容易出错,也没必要!
int big = 123456789;//亿级别的大数字
float Big = big;
System.out.println(big);
System.out.println(Big);
丢失了精度,打印结果;
123456789
1.23456792E8
byte b = 0;//就是一个字节的空间
byte a = 10;//10也是一个字节的空间
System.out.println(a);
System.out.println(b);
byte c = 100;//8位二进制
System.out.println(c);
byte d = 127;
System.out.println(d);
//byte e = 128;
byte f = -128;
//byte g = -129;
如果把注释拿掉,编译就会报错!已经超出了byte的存储范围!(-128到127),总之就是同样的类型(比如都是整型),则存储空间小的可以向大的转化,反之不行,对于存储空间一样的不同类型,也尽量不转化,比如double和long,int和float,不同类型下,存储空间小的可以向大的转化,比如int到double。
byte b = 10;
int iA = 123456789;
//byte转为int,精度永远不丢失
int i = b;
System.out.println(i);//10
//byte转为更高的更是如此
long l = b;
System.out.println(l);//10
再看一个精细的实验;
public class lab2 {
public static void main(String[] args) {
// byte类型没有后缀标识,默认就是和int型一样
byte byteNum = 1;
// 赋值long型,对不起,编译都出错了
// byte byteU = 9l;
// 同理,short类型也不用后缀,编译器自动检测范围
short shortNum = 1111;
// 同理,赋值long,报错
// shortNum = 1l;
// int的也是默认没有后缀
int intNum = 3413;
// 同理,即使不超出范围,赋值long也不行!!!!!!
// int intN = 1231L;
// 给long赋值,int范围内的写L和不写L都行
long longNum = 1234;
// 但是超出int的数值,必须加L才能编译过去
long longN = 12345678902L;
// 针对浮点型
float floatNum = 111;
// 比如,int赋值给float,编译虽然能通过,但是代码多了很容易出错,丢失精度!
float float_a = 12341;
// 记住,不到万不得已,不要随便这样用,习惯不好,思维体现的是不严谨性。
int iA = 12345155;
float floatInt = iA;
System.out.println(floatInt);// 1.2345155E7 ok!
int iB = 1411412413;
floatInt = iB;
System.out.println(floatInt);// 1.41141235E9 flase!
// 同理,long型直接赋值给float也是可以的,但是不严谨
float float_long = 1231L;
float float_b = 1231451111;
System.out.println(float_b);// 1.23145114E9 flase!
// 这样是不行的,没有后缀d的默认为double,不能编译通过
// float float_c = 13.521;
// float类型的浮点数,必须加后缀f区分!!!
float f = 111.1f;
// 同样,不能把double赋值给float,编译出错,和long赋值给int出错一个道理
// f = 123D;
// double类型的没有后缀,那么默认就是double
double doubleNum = 1.4124;
// int类型可以赋值给double类型
doubleNum = 12313;
// long型可以直接赋值给double,但是同样注意精度问题!!!!!
doubleNum = 123123L;
// float类型可以直接赋值给double
doubleNum = 21.13F;
// 把大的赋值给小的(大小说的是存储空间占据的字节数),编译出错
// 比如double赋值给byte,编译出错
// byteNum = 1.31D;
// double赋值short类型,编译报错,即使这个值没有超出short类型的取值范围 。
// short shortNum = 1.0D;
// double赋值int,编译时报错,都是同理。
// int intAB = 1.0D;
// double赋值给一个long变量,编译报错!!!!倒过来可以的,但是有时会发生精度损失。
// long longAB = 1.0D;
// char类型,必须是单个字符赋值
char charA = 'a';
// 这样的串儿不行
// char a = "412d"
// char a = '21';
// 可以把int的赋值给char,当然必须是范围内的,不过不建议这样乱用。(反过来当然更可以了!!!)
char chaB = 1231;
// 但是把long,float,double的赋值给char就编译出错!即使没有超过范围!
// chaB = 134144l;
// charA = 12.12F;
}
}
总的来说,就是小的转大的,尽量避免大的转小的。
JAVA中的数值类型不存在无符号数,它们的取值范围是固定的,不会随着机器硬件环境或者操作系统的改变而改变。实际上,JAVA中还存在另外一种基本类型void,它也有对应的包装类 java.lang.Void,不过我们无法直接对它们进行操作。对于数值类型的基本类型的取值范围,我们无需强制去记忆,因为它们的值都已经以常量的形式定义在对应的包装类中了。
public class lab1 {
public static void main(String[] args) {
// java的基本数据类型
// 类型的位数
System.out.println(Byte.SIZE);// 8
// 最大值
System.out.println(Byte.MAX_VALUE);// 127
// 最小值
System.out.println(Byte.MIN_VALUE);// -128
// short类型
System.out.println(Short.SIZE);// 16
System.out.println(Short.MAX_VALUE);// 32767
System.out.println(Short.MIN_VALUE);// -32768
// int类型
System.out.println(Integer.SIZE);// 32
System.out.println(Integer.MAX_VALUE);// 2147483647
System.out.println(Integer.MIN_VALUE);// -2147483648
// long int类型
System.out.println(Long.SIZE);// 64
System.out.println(Long.MAX_VALUE);// 9223372036854775807
System.out.println(Long.MIN_VALUE);// -9223372036854775808
// double类型
System.out.println(Double.SIZE);// 64
System.out.println(Double.MAX_VALUE);// 1.7976931348623157E308
System.out.println(Double.MIN_VALUE);// 4.9E-324
// float 类型
System.out.println(Float.SIZE);// 32
System.out.println(Float.MAX_VALUE);// 3.4028235E38
System.out.println(Float.MIN_VALUE);// 1.4E-45
// char类型
System.out.println(Character.SIZE);// 16
System.out.println((int) Character.MAX_VALUE);// 65535
System.out.println((int) Character.MIN_VALUE);// 0
}
}
浮点数是以科学记数法的形式输出的,结尾的“E+数字”表示E之前的数字要乘以10的多少倍(-就代表是除以10的多少倍)。
比如;1.1E2意思是说,1.1x100=110
再看,如果二元操作符的两边的变量类型不一致,那么一定是先类型提升为同一个类型!再计算!有如下规律;
未带有字符后缀标识的整数默认为int类型;未带有字符后缀标识的浮点数默认为double类型。
// 定义一个短整型数据
short shortNum = 12314;
// 两个参数中,一个是int,一个short int则自动类型提升错误!提升的结果为int型,它不能赋值给short类型
// shortNum = shortNum + 12;
// 没问题,不需要类型提升,并且没有超出范围
shortNum = 31 + 214;
//针对+=符合赋值符号,java的编译器有特殊处理,不会报错!!!!!这是需要注意的!
shortNum += 1;
对于一个是浮点数(float或者double),一个是整型(int,short,long,byte),那么有如下的规律
1、如果一个是double类型,则另一个提升为double
2、否则的话,如果一个是float类型,则另一个提升为float.
3、否则,如果一个是long类型,那么另一个提升为long类型
4、否则,两个参数都被提升为int型
=======================================================================================================================
小结;
1、如果一个整数的值超出了int类型能够表示的范围,则必须增加后缀“L”(建议用大写,防止混淆),表示为long型。
2、带有“F”后缀的整数和浮点数都是float类型的;
3、带有“D”后缀的整数和浮点数都是double类型的。
4、编译器会在编译期对byte、short、int、long、float、double、char型变量的值进行检查,如果超出了它们的取值范围就会报错。
5、int型值理论上是可以赋给所有数值类型的变量的,long型值理论上可以赋给long、float、double类型的变量,但是注意精度的丢失!!!!!!
6、float型值可以赋给float、double类型的变量,double型值只能赋给double类型变量!!!!
7、只要两个操作数中有一个是double类型的,另一个将会被转换成double类型,并且结果也是double类型,否则,只要两个操作数中有一个是float类型的,另一个将会被转换成float类型,并且结果也是float类型;否则,只要两个操作数中有一个是long类型的,另一个将会被转换成long类型,并且结果也是long类型;否则,两个操作数(包括byte、short、int、char)都将会被转换成int类型,并且结果也是int类型。
当使用+=、-=、*=、/=、%=、运算符对基本类型进行运算时,遵循如下规则:
运算符右边的数值将首先被强制转换成与运算符左边数值相同的类型,然后再执行运算,且运算结果与运算符左边数值类型相同。
========================================================================================================================
当然,还有一招,那就是强制类型的转化!
如果,程序里一定要把double转化为int!那么可以这样;
int i = 12312;
double d = 1.31;
i = (int)d;
编译通过,没问题!打印i的值;结果是1,因为强制类型转化之后,小数点后面的被截断,d成了整型了!
如果在实际程序中,想把一个小数,四舍五入怎么办?那么可以使用Math.round方法。round单词本身具有四舍五入的含义。
double double_round = 1.1111124;
System.out.println(Math.round(double_round));
打印1
注意;
1、如果在四舍五入操作之后,想去赋值给整型,那么还是需要进行强制类型转换!因为
long java.lang.Math.round(double a)
Returns the closest long
to the argument, with ties rounding up
返回的是long类型,赋给int型,有可能产生精度丢失的问题,不确定!故编译报错!比如;
long longNUM = Math.round(double_round);.
就不用强制类型转化。完全符合规范。
2、如果强制类型转换的时候,超出了目标类型的范围,那么截断的时候,就有可能得到另外一个完全不同的值。