java编程之旅第四章——变量下(数据类型转换)

时间:2023-02-22 19:24:24

 5:数据类型转换

* 数据参与运算(重要)

    * A:整型,字符型,浮点型的数据在混合运算中相互转换,转换时遵循以下原则:

            * 容量小的类型与容量大的类型进行计算,默认转换为容量大的数据类型;数据类型按容量大小排序为:
            * byte,short,char->int->long->float->double
            * byte 和 short运算时不能和char之间互相转换,byte可以直接赋值给short,但是他们三者在计算时首先会转换为int类型
            * 容量大的数据类型转换为容量小的数据类型时,要加上强制转换符,但可能造成精度降低或溢出;使用时要格外注意。
            * 有多种类型的数据混合运算时,系统首先自动的将所有数据转换成容量最大的那一种数据类型,然后再进行计算。


      隐式转换运算举例:(需要多敲

       先来介绍一下“+”,“=”这两个符号,“+”是算术运算符中的加法,这和数学中的是一样的,“=”是赋值运算符,将右边的值赋予左边,关于运算符的介绍会在后边学习。另外我会将输出语句System.out.println();简写为sop();下边我们来做隐式转换的举例。


       例一:System.out.println(3+4);
    int a = 3 ;
    int b = 4 ;
   System.out.println(a+b);//输出结果为7


int c  =  a+b;
System.out.println(c);//左边声明数据类型为int的变量c,右边两个int数据类型相加结果还是int并赋值给c,输出c的值为7。


//byte d = a+b ;//错误: 可能损失精度
//System.out.println(d);
// = 是个运算符 赋值运算符
//编译器在编译过程中将a+b是int类型,在编译的时候并没有把结果算出来,以为a,b是变量
//编译器不知道你计算后的结果.
//a+b 在编译的时候还是当成int ,4个字节 赋给一个字节的byte
        
int x = 3 ;
byte y = 4;
System.out.println(x+y);//默认int类型
int z = x+y;
System.out.println(z);//默认int类型


    * B:强制转换符

        * 格式:(数据类型)(要被转换的数据)
例如:byte b = (byte)(300);//byte取值范围为-128~127,定义超过取值范围的数值,会报错。所以要在 300前边加上 byte


例子2; byte m = x+y;//可能会损失精度 ,需要强转,byte m = byte(x+y);
          System.out.println(m);


        原理:/* byte b = 130;有没有问题?如果我想让赋值正确,可以怎么做?结果是多少呢? */
class DataTypeTest {
public static void main(String[] args) {
//byte b = 130;//损失精度
byte b = (byte)130;
System.out.println(b);
} }
/*
     130 是int类型  4个字节  0b10000010
 原码 000000000 00000000 00000000 10000010
 参与运算的是补码
   000000000 00000000 00000000 10000010


   做强制转换
     10000010  -----------补码
 你想要知道这个数据具体是多少,应该求出原码
  补码:10000010
  反码:10000001
  原码:11111110
    -126
*/

例三:
/*               思考题1:请问下面这个有没有问题
double d = 12.345;
float f = d;   有:损失精度
思考题2:看看下面两个定义有没有区别呢?
float f1 = (float)12.345;
float f2 = 12.345f;
*/
class DataTypeTest2 {
public static void main(String[] args) {
float f1 = (float)12.345;
//定义的常量是double类型,然后做了一个强制转换成float类型,再赋值给f1
float f2 = 12.345f;
//定义的常量就是float类型,然后再赋值给f2
System.out.println("Hello World!");
}
}


  例四;/*
  A:案例演示
面试题:看下面的程序是否有问题,如果有问题,请指出并说明理由。
byte b1 = 3;
byte b2 = 4;
byte b3 = b1 + b2;
byte b4 = 3 + 4;
   那么byte b5 = b1+1;   


    编译问题 b1+b2是变量 变量做运算在编译时期 编译器不确定b1+b2是多少  
会将加后 的结果以默认类型int来处理.
常量是不变的,编译器就已经知道了3+4的结果,然后检查得到的结果是不是在byte范围内
常量与变量相加,会变成变量的数据类型
*/
class  DataTypeTest3{
public static void main(String[] args) {


byte b1 = 3;
byte b2 = 4;
//byte b3 = b1 + b2;//损失精度
//因为byte变量参与运算的时候,自动转换成int类型参与运算,
//编译器在处理的时候(因为b1和b2是变量),不知道变量的值,
//默认将b1+b2当做int类型处理,然后发现赋值的要给byte类型,因为int是4个字节,byte是一个字节,
//所以就出现了损失精度问题

byte b4 = 3 + 4;
//不会报错:因为3跟4 是常量,编译器在处理常量(在程序运行中不发生改变)的时候会先给它们计算出结果
//判断结果是不是在int范围内,是,没问题,然后再去看前面赋值的变量的数据类型,判断结果是不是在byte
//范围内.所以不报错
System.out.println(b4);
byte b5 = b1+1;//损失精度
//编译器在处理的时候(变量与常量相加),相当于处理变量因为int是4个字节,byte是一个字节,



}
}


    * C:字符型参与运算

        * 首先会去找对应字符的unicode码值。然后运算。关于Unicode码表请自行百度百科。
        * char 类型取值范围0~2(16)-1,我就有了一个问题?能不能把整数直接赋值给char类型的变量




    * D:布尔型参与运算

        * 不能参与运算


    * E:字符串参与运算

        * 它是和参与运算的数据相连接组成了一个新的字符串。


例子五:
/*
字符参与运算
System.out.println('a');
System.out.println('a' + 1);


ASCII码表的概述
记住三个值:
'0' 48
'A' 65
'a' 97
  Java语言中的字符char可以存储一个中文汉字吗?为什么呢?
可以。因为Java语言采用的是Unicode编码。Unicode编码中的每个字符占用两个字节。
所以,Java中的字符可以存储一个中文汉字

字符串参与运算时:
   +就不是加法了,是一个连接符
   字符串左边或右边有+的时候,+就是一个连接符,得到的结果是字符串




*/
class DataTypeTest4 {
public static void main(String[] args) {
System.out.println('a');//a
System.out.println('a' + 1);//98
//看来字符a对应一个值 97 
System.out.println('你');
    
System.out.println("hello" + 'a' + 1);//helloa1 
//   "helloa"+1  helloa1       
System.out.println('a' + 1 + "hello");//98hello
//    98hello




System.out.println("5+5="+5+5);
//5+5=55
System.out.println(5+5+"=5+5");
//10=5+5
}
}


        
    
    * 思考:哪句是编译失败的呢?为什么呢?
    > byte b1=3,b2=4,b;  
    > b=b1+b2;
    * (1)byte,short,char三种数据类型在内存中运算的时候会自动类型提升为int去运算
    * (2)b1和b2是两个变量值,jvm无法判断里面值的大小
    > b=3+4;    
    * java 编译器有常量优化机制,在编译的时候已经将3+4的结果赋值给b了