Java基础–数据类型转换
/*
当数据类型不一样时,将发生数据类型转换。
自动类型转换(隐式)
1.特点:代码不需要进行特殊处理,自动完成
2.规则:数据范围从小到大,与数据字节不一定相关
*/
public class Demo01DateType{
public static void main(String[] args){
System.out.println(1024);
//1024是整数,默认是int类型
System.out.println(3.14);
//3.14是浮点数,默认是double类型
long num1 = 100;
System.out.println(num1);
//100
//左边是long数据类型,右边100是默认的int类型,左右不一样
//等号代表赋值,将右边代表的int常量,交给左边的long变量进行存储
//int-->long,符合数据范围从小到大的要求
//这样这一行代码实现了自动数据类型转换
double num2 = 2.5F;
System.out.println(num2);
//左边是double类型,右边是float类型,左右数据类型不一样
//但是float-->double符合数据范围从小到大的原则
//也可以实现自动数据类型转换
float num3 = 30L;
System.out.println(num3);
//30.0
//左右两边的数据类型不一样
//但是long-->float 符合数据范围从小到大的原则,虽然long是8个字节,float是4个字节但是,float的数据范围更大
//这样也可以实现数据类型自动转换
}
}
/*
强制数据类型转换
1.特点:代码需要特殊的格式处理,不能自动完成
2.格式:范围小的数据类型 范围小的变量名 = (范围小的数据类型) 原本范围大的数据;
注意事项
1.一般不建议使用,因为可能发生数据精度损失,数据溢出
2.byte/short/char这三种数据类型都可以发生数学运算,例如“+”
3.byte/short/char这三种数据类型在进行数学运算的时候,首先会被转换成int类型
4.boolean类型不能发生数据类型转换
*/
public class Demo02DateType{
public static void main(String[] args){
int num1 = (int) 100L;
System.out.println(num1);
//100
//左右两边数据类型不一样
//long-->int,不符合从小到大的要求
//所以不可以发生自动数据类型转换
//但是采取强制数据类型代码格式,就可以强制进行数据类型的转换
//long-->int
int num2 = (int) 6000000000L;
System.out.println(num2);
//输出1705032704,这说明数据溢出,因为int数据范围比long小
//double-->int
int num3 = (int) 3.99;
System.out.println(num3);
//输出3,并不是四舍五入,所有的小数位都会被舍弃,这说明数据精度损失
char zifu1 = 'A';
//这是一个字符数据类型,里面是大写字母A
System.out.println(zifu1+1);
//输出为66。?
char zifu2 = '中';
System.out.println(zifu2+1);
//输出为20014。
//计算机底层会用一个二进制数字代表‘A’,就是65
//一旦char类型进行数学计算,那么字符就会按照一定的规则转换成一个数字(ACSII编码表)
byte num4 = 20;
//右侧数值不能超过左边数据类型的取值范围
byte num5 = 30;
//byte result = num4 + num5;//错误写法
/*
上面这行代码出错,因为左边变量的数据类型是byte类型,byte类型在进行数学运算的时候,首先会转换成int类型,因此运算结果是int类型
*/
//byte + byte --> int + int -->int
int result = num4 + num5;
System.out.println(result);
//输出为50
short num6 = 80;
short result2 = (short) (num4 + num6);
System.out.println(result2);
//byte + short -->int + int --> int
//int result2 = num4 + num6;
//System.out.println(result2);
//byte + short --> int + int --> int -->(short)强制转换--> short
//int强制转换成short时必须保证逻辑上结果的真实大小不超过short取值范围,否则发生数据溢出
}
}
数据类型转换中的优化
/*
对于byte/short/char三种数据类型来说,如果右侧赋值的数值没有超过三种数据类型的取值范围,那么javac编译器将会自动隐含地为赋值语句补上一个强制转换代码(byte)/(short)/(char).
如果超出取值范围,那么编译器会直接报错
*/
public class Demo12Notic{
public static void main(String[] args){
byte num1 = 30;
System.out.println(num1);
//30
//这里将int类型常量赋值给byte类型变量没有发生错误
//这是因为右侧int类型常量的取值范围没有超过左侧byte类型变量的取值范围
//因此javac编译器会执行强制类型转换
//但是这种强制类型转换是隐式的
//在.class文件中执行的代码为
//byte num1 = (byte) 30;
//byte num2 = 128;
//这行代码是错误的,因为128超过了byte类型变量的取值范围
//javac编译器会直接报错
char zifu = 65;
System.out.println(zifu);
//A
//65没有超出char类型变量的取值范围
//因此在.class文件中执行的代码为
//char zifu = (char) 65;
//现将65按照ASCII表转换成char类型字符
//然后将转换的结果 A 打印输出
}
}
/*
在给变量进行赋值的时候,如果右侧表达式全是常量,没有任何变量那么在javac编译器中将会直接将若干个常量表达式进行计算并将结果赋值给左侧变量
short a = 5 + 8;
在.class文件中执行的是
short a = 13;
这称之为“编译器的常量优化”
但是,一旦右侧表达式中出现变量,那么就不能进行这种优化
*/
public class Demo13Ntice{
public static void main(String[] args){
short num1 = 10;
short a = 5;
short b = 8;
//以上三行赋值语句都是正确的,因为右侧常量数值没有超过左侧short类型变量的取值范围,这时候javac编译器会进行隐含地强制数据类型转换
//short result = a + b;
//错误写法
//因为这里a和b都是int类型的变量,他们的运算结果还是int类型,而且此时不满足自动数据类型转换的要求,因为int类型的取值范围要大于short类型的取值范围
short result = 5 + 8;
System.out.println(result);
//13
//上面两行代码是正确的,满足“编译器的常量优化”要求
short result2 = 5 + a + 8;
//这是错误的,不满足“编译器的常量优化”要求
//编译器会直接在读到这行代码的时候报错
}
}