Java数值类型提升机制

【1】数值提升

数字类型提升机制被用于算术运算符上,通常使用场景为:

  • 同一类型转换
    有时可以使代码更清晰。
  • 拓宽原始类型转换
    指byte、short、int、long、float、double由低向高转换。
  • 自动拆箱转换
    基础类型引用类的拆箱方法,如r.intValue()。

数值提升用于将算术运算中的操作数转化为一个相同的类型以便于运算,具体分为两种情况:一元数值提升和二元数值提升。


【2】一元数值提升

某些运算符将一元数值提升用在了单操作数运算中,其必定能得到一个数字类型的值,规则如下:

  • if 操作数是编译时类型Byte、Short、Character或Integer,那么它会先拆箱为对应的原始类型,然后拓宽为int类型。
  • else if 操作数为编译时类型Long、Float或Double,那么就直接拆箱为对应的原始类型。
  • else if 操作数是编译时类型byte、short、char或int,那么就拓宽为int类型。
  • else 保持原样。

一元数值提升还用在以下情境的表达式中(提升为int):

  • 数组创建表达式的维度
  • 数组索引表达式的索引
  • 正号运算符(+)的操作数
  • 负号运算符(-)的操作数
  • 按位补运算符(~)的操作数
  • 移位运算符(>>, >>>, << )的每一个操作数。注意移位运算并不会使两边的操作数提升到相同类型,如 A << B 中若B为long类型,A并不会被提升到long。

注意:自增和自减单目运算符同样也会进行类型提升,但运算后会自动进行强制类型转换,如
byte a = 127;
a++; // a在运算后为int类型,转为byte截断后变成-128
等价于
byte a = (byte)128;

示例如下:

class Test {
    public static void main(String[] args) {
        byte b = 2;
        int a[] = new int[b];  // 维度表达式提升
        char c = '\u0001';
        a[c] = 1;              // 索引表达式提升
        a[0] = -c;             // 负号 提升
        System.out.println("a: " + a[0] + "," + a[1]);
        b = -1;
        int i = ~b;            // 按位补提升
        System.out.println("~0x" + Integer.toHexString(b)
                           + "==0x" + Integer.toHexString(i));
        i = b << 4L;           // 移位提升(左操作数)
        System.out.println("0x" + Integer.toHexString(b)
                           + "<<4L==0x" + Integer.toHexString(i));
    }
}

输出:
a: -1,1
~0xffffffff==0x0
0xffffffff<<4L==0xfffffff0

【3】二元数值提升

当二元运算符的操作数皆可转化为数字类型时,那么将采用如下二元数值提升规则:

  • 如果任一操作数为引用类型,那么对其进行自动拆箱。
  • 拓宽类型转换被应用于以下情况:
    • if 某一操作数为double类型,那么另一个也转为double
    • else if 某一操作数为float类型,那么另一个也转为float
    • else if 某一操作数为long类型,那么另一个也转为long
    • else 两个操作数都转为int

二元数值提升应用于以下运算符上:

  • 乘法运算符: * 、 / 、%
  • 针对数字类型的加减运算符: + 、 -
  • 数值比较运算符:< 、<= 、> 、>=
  • 数值相等比较运算符: == 、 !=
  • 整数按位运算符: & 、^ 、|
  • 某些情况下的条件运算符 ? : 中

注意:混合赋值运算符同样也会自动进行强制类型转换,如
byte a = 127;
a += 1; // a在运算后为int类型,转为byte截断后变成-128

示例如下:

class Test {
    public static void main(String[] args) {
        int i    = 0;
        float f  = 1.0f;
        double d = 2.0;
        // int*float 先是被提升为 float*float,然后
        // float==double 被提升为 double==double:
        if (i * f == d) System.out.println("oops");

        // char&byte 被提升为 int&int:
        byte b = 0x1f;
        char c = 'G';
        int control = c & b;
        System.out.println(Integer.toHexString(control));

        // 此处 int:float 被提升为 float:float:
        f = (b==0) ? i : 4.0f;
        System.out.println(1.0/f);
    }
}

输出:
7
0.25

条件运算符中的类型提升 :https://blog.csdn.net/J080624/article/details/81836930

猜你喜欢

转载自blog.csdn.net/J080624/article/details/81837155
今日推荐