引用数据类型自动类型提升自动类型转换强制类型转换

Posted wxlmdx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了引用数据类型自动类型提升自动类型转换强制类型转换相关的知识,希望对你有一定的参考价值。

10.7.2 引用数据类型

/*
* 1、与 基本数据类型 对应的是 引用类型
* 2、在基本数据类型的变量中存储的就是相应类型的数值
* 3、在引用类型的变量中存储的是一个内存地址(通过这个地址可以找到真正的数据)
*/
public class Snake {
?
  public static void main( String[] args ) {
?
     int first = 100 ; // int 类型的变量 first 中直接存储了数值 100
     System.out.println( first );
?
     // 对于 main 方法的参数 args 来说就是一个 引用类型 的变量 (引用变量)
     System.out.println( args ); // 所有引用变量中都存储了一个内存地址
?
     // 通过这个内存地址可以找到真正的数据所在的位置
     int n = args.length ; // 获取数组长度
     for( int i = 0 ; i < n ; i++ ) {
        System.out.println( args[ i ] ) ;
    }
?
  }
?
}
?

10.7.3 自动类型提升

?
/**
* 1、表示数字的基本数据类型的【自动类型提升】
* 2、按照能够表示的数字范围从小到大排列依次是 byte 、 short 、int 、long 、float 、double
* 3、将 数字范围较小的类型的变量的值 赋值给 数字范围较大的类型的变量 时,会发生【自动类型提升】
*/
public class Chicken {
?
   public static void main( String[] args ) {
?
       // 8bit     16bit       32bit       64bit       32bit           64bit
       // byte --> short -->   int   -->   long ---> float   ---> double
?
       // 声明一个 byte 类型的、名称为 first 的 变量并为其赋值
       byte first = 100 ; // 100 对应的二进制形式刚好是用 8 个二进制位所能表示的
       System.out.println( first );
?
       short second = first ; // 本来是 byte 类型的 first 变量中存储的数值 会提升为 short 类型
       System.out.println( second );
?
       // int third = second ; // 本来是 short 类型的 second 变量中存储的数值 会提升为 int 类型
       int third = first ; // 本来是 byte 类型的 first 变量中存储的数值 会提升为 int 类型
       System.out.println( third );
?
       long fourth = first ; // 本来是 byte 类型的 first 变量中存储的数值 会提升为 long 类型
       System.out.println( fourth );
?
       float fifth = first ; // 本来是 byte 类型的 first 变量中存储的数值 会提升为 float 类型
       System.out.println( fifth );
?
       double sixth = first ; // 本来是 byte 类型的 first 变量中存储的数值 会提升为 double 类型
       System.out.println( sixth );
?
  }
?
}
?
?
/**
* 1、在 Java 语言中,如果遇到 范围比 int 小的类型发生运算时,首先需要提升为 int 类型后再运算
* 2、在 Java 语言中,两个 float 类型的变量相加后仍然是 float 类型 ( Java 8 和 Java 11 测试通过 )
* 3、在 Java 语言中,一个 float 类型的数值 与 一个 double 类型的数值 发生运算时,float 数值首先提升为 double 类型后再运算
*/
public class Pig {
?
   public static void main( String[] args ) {
?
       byte first = 100 ;
       byte second = 50 ;
?
       // byte third = first + second ; // 【编译失败】错误: 不兼容的类型: 从int转换到byte可能会有损失
       // 两个 byte 类型的 变量 相加时,会首先自动类型提升为 int 类型,再运算
       int third = first + second ;
       System.out.println( third );
?
       short fourth = 100 ;
       short fifth = 200 ;
?
       // short sixth = fourth + fifth ; // 【编译失败】错误: 不兼容的类型: 从int转换到short可能会有损失
       // 两个 short 类型的 变量 相加时,会首先自动类型提升为 int 类型,再运算
       int sixth = fourth + fifth ;
       System.out.println( sixth );
?
       // byte result = first + fourth ; // ???
       // short result = first + fourth ; // ???
       // int result = first + fourth ; // ???
       // long result = first + fourth ; // ???
?
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
       float one = 3.14F ;
       float two = 3.14F ;
?
       float three = one + two ; // 注意: 这里至少在 Java 8 中测试是通过的
       System.out.println( three );
?
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
       double four = 3.1415926 ;
?
       // float five = one + four ; // 【编译失败】错误: 不兼容的类型: 从double转换到float可能会有损失
       double five = one + four ;
       System.out.println( five );
?
  }
?
}
?

 

10.7.4 自动类型转换

技术图片

 

?
/**
* 1、short 和 char 之间不能实现【自动类型转换】
* 2、short 和 char 都可以【自动类型提升】为 数字范围较大 的类型 ( int 、long 、float 、double )
*/
public class Dog {
?
   public static void main( String[] args ) {
?
       // short : 16bit
       short first = 97 ;
       System.out.println( first );
       // char second = first ; // 【编译失败】错误: 不兼容的类型: 从short转换到char可能会有损失
       int second = first ; // 本来是 short 类型的 first 变量中存储的数值会自动提升为 int 类型后再赋值给 second 变量
       System.out.println( second );
?
       // char : 16bit
       char third = ‘a‘ ;
       System.out.println( third );
       // short fourth = third ; // 【编译失败】错误: 不兼容的类型: 从short转换到char可能会有损失
       int fourth = third ; // 本来是 char 类型的 third 变量中存储的数值会自动提升为 int 类型后再赋值给 fourth 变量
       System.out.println( fourth );
?
  }
?
}
?

10.7.5 强制类型转换

?
public class NarrowingPrimitive {
?
   public static void main(String[] args) {
?
       // 【 1 】In the first step,
       // the floating-point number is converted either to a long , if T is long, or to an int, if T is byte, short, char, or int, as follows:
?
       // 【 1.1 】If the floating-point number is NaN ( Not a Number ), the result of the first step of the conversion is an int or long 0 .
       double nan = Double.NaN ; // NaN 是 Double 类中声明的一个常量
       System.out.println( nan );
       System.out.println( "byte : " + (byte) nan + " , short : " + (short) nan + " , int : " + (int) nan + " , long : " + (long) nan );
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
       // 【 1.2 】Otherwise, if the floating-point number is not an infinity, the floating-point value is rounded to an integer value V,
       //             rounding toward zero using IEEE 754 round-toward-zero mode (§4.2.3). Then there are two cases:
?
       // 【 1.2.1 】If T is long, and this integer value can be represented as a long, then the result of the first step is the long value V
       double lv = 0xFFFFFFFFL + 0.625; // 假设 double 变量中存储的数值的整数部分恰好是 long 类型可以表示的整数
       System.out.println( lv );
       System.out.println( "long : " + (long) lv );
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
       // 【 1.2.2 】Otherwise, if this integer value can be represented as an int, then the result of the first step is the int value V.
       double iv = 0xFFFFFF + 0.625; // 假设 double 变量中存储的数值的整数部分恰好是 int 类型可以表示的整数
       System.out.println( iv );
       System.out.println( "int : " + (int) iv );
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
       // 【 1.3 】Otherwise, one of the following two cases must be true:
?
       // 【 1.3.1 】The value must be too small ( a negative value of large magnitude or negative infinity ),
       //                 and the result of the first step is the smallest representable value of type int or long.
       // double negative = Double.NEGATIVE_INFINITY ; // NEGATIVE_INFINITY 是 Double 类中定义的常量,表示负无穷大
       double negative = 0x8000_0000_0000_0000L - 10000.0 ; // 一定要让 long 类型的值 减去 double 类型的数值
       System.out.println( negative );
       System.out.println( "int : " + (int) negative + " , long : " + (long) negative );
       // int min value : 0x8000_0000 ( 0b1000_0000_0000_0000_0000_0000_0000_0000 )
       // long min value : 0x8000_0000_0000_0000L
?
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
       // 【 1.3.2 】The value must be too large ( a positive value of large magnitude or positive infinity ),
       //                 and the result of the first step is the largest representable value of type int or long.
       // double positive = Double.POSITIVE_INFINITY ; // POSITIVE_INFINITY 是 Double 类中定义的常量,表示正无穷大
       double positive = 0x7FFF_FFFF_FFFF_FFFFL + 10000.0 ; // 一定要让 long 类型的值 加上 double 类型的数值
       System.out.println( positive );
       System.out.println( "int : " + (int) positive + " , long : " + (long) positive );
       // int max value : 0x7FFF_FFFF ( 0b0111_1111_1111_1111_1111_1111_1111_1111 )
       // long max value : 0x7FFF_FFFF_FFFF_FFFFL
?
       double x = 0xFFFF + 0.1415926 ;
       //【 2 】In the second step:
       //【 2.1 】 If T is int or long, the result of the conversion is the result of the first step.
       System.out.println( "int : " + (int) x + " , long : " + (long) x );
?
       //【 2.2 】 If T is byte, char, or short, the result of the conversion is the result of a narrowing conversion to type T of the result of the first step
       System.out.println( "byte : " + (byte) x + " , char : " + (char) x + " , short : " + (short) x );
?
       System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );
?
        // (byte) positive 表示从 long max value 中截取 低 8 位 : 1111_1111
        System.out.println( (byte)0b1111_1111 );
        // 将8位的 1111_1111 当做补码,可以获取到相应的反码为 1111_1110 ,遂后保持符号位不变、数值部分逐位取反得到原码 1000_0001

        // (short) positive 表示从 long max value 中截取 低 16 位 : 1111_1111_1111_1111
        System.out.println( (short)0b1111_1111_1111_1111 );
        // 将16位的 1111_1111_1111_1111 当做补码,可以获取到相应的反码为 1111_1111_1111_1110 ,遂后保持符号位不变、数值部分逐位取反得到原码 1000_0000_0000_0001
?
  }
?
}
?

 

以上是关于引用数据类型自动类型提升自动类型转换强制类型转换的主要内容,如果未能解决你的问题,请参考以下文章

类型转换 隐式转换 自动提升 强制转换

Java基本数据类型转换

Java基本数据类型转换

今天聊一聊Java引用类型的强制类型转换

引用类型的转换

数据类型转换