Java的基本数据类型是如何进行自动变量提升的——数据类型提升

基本数据类型转换

1、基本数据类型转换概念

转换原因

Java是强类型语言,数据类型之间不能随意转换,但运算时数据类型不匹配,所以需要转换.

2、数据类型转换分类

  • 自动类型提升
  • 强制类型转换

2.1、自动类型提升

  1. 概念

范围小的数据类型可以直接转换为范围大的数据类型

  1. 数据类型范围大小排序

  2. 要点

  1. 数据类型兼容 byte short char int long .... 都属于数字类型 都是兼容的
    boolean 是参与类型转换
  2. 小范围的数据类型 转换为 大范围的数据类型
  1. 案例
  public class Demo3{
  	public static void main(String[] args) {
 		// 自动类型提升
  		// 第一条线  byte --> short --> int --> long --> float --> double
  		//byte b = 20;//20 字面值默认的类型是 int 但是当赋值给b 此时的20就是 byte 类型   
   		//short s = b;// 20 被提升为short类型
   		//int i = s; // 20 --> int
  		//long l = i; //20 --> long
  		//float f = l;//20 --> float 
   		//double d = f;//20 --> double
   		//System.out.println(f);
 
  		//第二条线路 char --> int --> long --> float --> double 
  		char c = 'A';// A ---> 编码 ---> 二进制的 65  
  		System.out.println(c);// 二进制的 65 ---> 解码 ---> A
  
  		int i = c;// 65  ---> int 
  		System.out.println(i);
  
  		long l = i;
  		float f = l;
  		double d = f;
  		System.out.println(d);
  
  	}
  }    

2.2、强制类型转换

  1. 概念

大范围数据类型的变量/常量 赋值 给一个小范围数据类型的变量,需要进行强制转换.

要求: 数据类型之间要兼容

  1. 格式

目标数据类型 变量名 = (目标数据类型)原数据类型变量名/原常量值;

  1. 注意事项
  1. 强制类型转换可能会损失精度,得到错误的数据.
  2. 小数类型强制转换为整数类型时,直接舍去小数部分,只保留整数部分.
  1. 案例
  public class Demo3{
  	public static void main(String[] args) {
  		// 强制类型转换
  		//int i = 128; // 20 --> int    
  		// 在Java程序的编译时期 编译器无法获取变量中的具体数值 
 		//  编译器是一个比较严谨的一个人 --> 保安 
  		//byte b = (byte)i;// 理论上  i的值 在byte的范围之内   
   		//System.out.println(b);
   
  		//  32        00000000  00000000   00000000   10000000  ---> 1*2^7  = 128
   		//   8                                        10000000  ----> 
  
   		double d = 12.1;
   		int i = (int)d;//  1.向上取整   2 向下取整    3 四舍五入 
   		System.out.println(i);	   		
   	}
   }
  

3、常量优化机制

概述

  1. 在编译时,整数常量的计算会直接算出结果,并且会自动判断该结果是否在该数据类型取值范围内
  2. 在为 byte short char 类型变量赋值的时候, 字面值类型默认都为int ,按照道理应该需要强制转换 ,但实际不强制转换也能编译通过,这是因为强制转换在编译器编译的时候会自动的加上。
public class Demo3{
	public static void main(String[] args) {
		//int i = 120+5;
		
		//byte b = 127+1;//在编译时期 会直接算出  127+1 = 128
		//int a = 2147483647;
		//int b = a + 1;//
		//System.out.println(b);

		byte b = (byte)10;// 10 类型是int    其实强制转换在编译器编译的时候,会自动的加上,从而减少了程序员的工作量 		
	}
}

4、在表达式中,进行的自动类型提升

表达式: 由 变量 常量 运算符 组成的式子 叫做表达式的值
特点: 每个表达式经过计算最终会得到一个值,这个值叫做表达式的值.
在表达式运算的过程中,也会发生类型的自动提升,这个机制直接决定表达式值的类型

规则:

  1. 当表达式中存在 double ---> 表达式的值类型为 double
  2. 反之 当表达式中存在float --> 表达式值的类型 float
  3. 再反之 当表达式中 存在long ---> 表达式的值类型为 long
  4. 其他情况都为 int

案例

public class Demo3{
	public static void main(String[] args) {
        //long a = 10;
        //long result = a + 20;
        //System.out.println(result);

        byte a = 10;
        byte b = 20;
        byte result =(byte)(a + b);
        System.out.println(result);

	}
}
public class Demo4{
	public static void main(String[] args) {
        byte a = 10;
        byte b = 20;
        //自加、自减操作不改变变量的数据类型,这里的自加、自减可以看作是自身的改变,所以不改变数据类型
        a += 2;
        System.out.println(a);
        //顺利编译运行,输出结果12
        b -= 3;
        System.out.println(b);
        //顺利编译运行,输出结果17  
	}
}
public class Demo5{
	public static void main(String[] args) {
        byte a = 10;
        byte b = 20;
        //需要强制类型转换
        a = a + 2;
        System.out.println(a);
        //编译运行:
        运行:javac Demo5.java
			Demo5.java:7: 错误: 可能损失精度
				a = a + 2;
		     		  ^
  			需要: byte
  			找到:    int
			1 个错误
        //若要顺利运行,需要进行强制转换
         a = (byte)(a + 2);
         System.out.println(a);       
        //顺利编译运行,输出结果12
	}
}

总结

自动类型提升:

即范围小的数据类型可以直接转换为范围大的数据类型

要点:

(1) 数据类型兼容 byte short char int long .... 都属于数字类型,都是兼容的. boolean 是参与类型转换
(2)小范围的数据类型 转换为 大范围的数据类型

强制类型转换

大范围数据类型的变量/常量 赋值 给一个小范围数据类型的变量,需要进行强制转换.

要求:

数据类型之间要兼容

注意:

  1. 强制类型转换可能会损失精度,得到错误的数据.
  2. 小数类型强制转换为整数类型时,直接舍去小数部分,只保留整数部分.

表达式自动类型提升

在表达式运算的过程中,也会发生类型的自动提升,这个机制直接决定表达式值的类型

规则:

  1. 当表达式中存在 double ---> 表达式的值类型为 double
  2. 反之 当表达式中存在float --> 表达式值的类型 float
  3. 再反之 当表达式中 存在long ---> 表达式的值类型为 long
  4. 其他情况都为 int

变量赋值时发生的数据类型提升要点:

一、 在编译时,整数常量赋值给变量的时候,会直接算出结果,并且会自动判断该结果是否在该数据类型取值范围内

注意:

(1)整数类型中字面值常量的默认类型是int类型
(2)long类型的变量在定义的时候,当字面值超过int范围需要在字面值后加 L / l,建议 L

二、 在为 byte short char 类型变量赋值的时候, 字面值类型默认都为int ,按照道理应该需要强制转换
例如:
    byte b = (byte)10;
        // 10 类型是int
     但事实上我们会发现:
         byte b = 10;
     照样能顺利编译运行,
    这是因为 整数类型常量赋值在编译器编译的时候,会自动的加上强制转换 ,从而减少了程序员的工作量( 仅限整数常量赋值,小数赋值、表达式赋值不会 )
         byte a = 123;
         byte b = a;
     能顺利编译运行;

         short a = 123;
         byte b = a;
     不能顺利编译运行;

         float a = 12.3;
     不能顺利编译运行;编译提示:
         需要: float
                         找到: double
                         1 个错误
     这是因为:
1. 小数类型的字面值常量默认类型是 double类型(且编译器不会自动强制转换)
2. float 类型变量在定义的时候,需要在字面值后加 F / f,建议F
3. double 类型的变量在定义的时候,可以在字面值后加 D / d,也可以不加.
4. 浮点型存储的数据是不精确的数据,所以在运算过程中,其结果也是不精确的.采用的科学计数法.

posted @ 2021-04-01 21:22  泰初  阅读(556)  评论(0)    收藏  举报