Java数值类型提升机制

简介: 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


【4】进制

① 十进制(最常用的进制)

  • 十进制就是满十进一的进制
  • 十进制当中一共有10个数字
    0 1 2 3 4 5 6 7 8 9
  • 十进制如何计数
    0 1 2 3 4 5 6 7 8 9 10 11 12 。。。 19 20 。。。29 30

② 二进制(计算机底层使用的进制)

满二进一

二进制中一共有2个数字

0 1

二进制如何计数

0 1 10 11 100 101 110 111 1000

所有的数据在计算机底层都是以二进制的形式保存的,计算机只认二进制

可以将内存想象为一个一个的小格子,小格子中可以存储一个0或一个1

内存中的每一个小格子,我们称为1bit(位)

bit是计算机中的最小的单位

byte是我们最小的可操作的单位

8bit = 1byte(字节)

1024byte = 1kb(千字节)

1024kb = 1mb(兆字节)

1024mb = 1gb(吉字节)

1024gb = 1tb(太字节)


③ 八进制(一般不用)

  • 满八进一
  • 八进制中一共有8个数字
    0 1 2 3 4 5 6 7
  • 八进制如何计数
    0 1 2 3 4 5 6 7 10 11 。。。 17 20 。。。27 30


④ 十六进制


满十六进一

十六进制中一共有16个数字

由于十六进制是满16才进位,

所以十六进制中引入了a b c d e f来表示 10 11 12 13 14 15

0 1 2 3 4 5 6 7 8 9 a b c d e f

十六进制如何计数

0 1 2 3 4 5 6 7 8 9 a b c d e f 10 11 12 。。。 1a 1b 1c 1d 1e 1f

20 21 22 。。。 2a 2b 2c 2d 2e 2f 30

我们在查看二进制数据时,一般会以十六进制的形式显示

目录
相关文章
|
4天前
|
Java 开发者
深入理解Java中的异常处理机制
【9月更文挑战第6天】在Java编程的世界中,异常处理是一块不可或缺的拼图。就像我们在生活中遇到意外时需要冷静思考解决方案一样,Java程序也需要通过异常处理来应对运行时出现的问题。本文将引导你了解Java异常处理的核心概念,并教你如何巧妙地使用try-catch语句和finally块来捕获和处理异常。
13 2
|
15天前
|
Java 程序员 UED
深入浅出Java异常处理机制
【8月更文挑战第27天】在Java编程的海洋里,异常如同突如其来的风暴,威胁着程序的平稳航行。掌握异常处理机制,就像学会驾驭这些风暴,确保船只(程序)能在风浪中稳健前行。本文将带你领略Java异常处理的魅力所在,从基础概念到高级技巧,一网打尽,助你在面对异常时从容不迫,化危为机。
|
12天前
|
消息中间件 算法 Java
深入浅出操作系统:进程管理的艺术掌握Java中的异常处理机制
【8月更文挑战第30天】在数字世界的舞台上,操作系统扮演着导演的角色,精心安排着每一个进程的表演。本文将揭开进程管理的神秘面纱,从进程的诞生到终结,探究它们如何在操作系统的指挥下和谐共舞。通过生动的比喻和直观的代码示例,我们将一同走进操作系统的核心,理解进程调度、同步与通信的内在机制,以及它们对计算生态的重要性。让我们跟随代码的节奏,一起感受操作系统的魅力吧!
|
10天前
|
自然语言处理 算法 Java
Java如何判断两句话的相似度类型MySQL的match
【9月更文挑战第1天】Java如何判断两句话的相似度类型MySQL的match
16 2
|
13天前
|
Java 编译器 开发者
Java中的异常处理机制
【8月更文挑战第30天】在Java编程中,异常处理是不可或缺的一部分。本文将探讨Java的异常处理机制,包括异常的概念、分类以及如何处理异常。我们将通过实际代码示例来展示如何在Java程序中捕获和处理异常,确保程序的稳定性和可靠性。无论你是初学者还是有经验的开发者,这篇文章都将帮助你更好地理解和应用Java的异常处理机制。
11 1
|
15天前
|
Java 程序员 开发者
深入理解Java异常处理机制
【8月更文挑战第27天】在Java编程的海洋中,异常处理是一艘必不可少的救生艇。它不仅能帮助我们在代码航行中避开暗礁,还能在风暴来临时保持程序的稳定。本文将带你探索Java异常处理的奥秘,从基础到高级,让你的程序更加健壮和用户友好。准备好了吗?让我们一起启航!
|
9天前
|
安全 Java API
Java线程池原理与锁机制分析
综上所述,Java线程池和锁机制是并发编程中极其重要的两个部分。线程池主要用于管理线程的生命周期和执行并发任务,而锁机制则用于保障线程安全和防止数据的并发错误。它们深入地结合在一起,成为Java高效并发编程实践中的关键要素。
8 0
|
11天前
|
Java 开发者
Java编程中的异常处理机制探究
【8月更文挑战第31天】在Java的世界中,异常处理是维护程序稳定性的重要工具。它像是一套精密的免疫系统,保护代码免受错误的侵袭,确保程序能够优雅地应对意外情况。本文将带你走进Java的异常处理机制,了解如何捕获和处理异常,以及自定义异常类的创建与应用,让你的代码更加健壮,运行更加顺畅。
|
11天前
|
开发者 C# 自然语言处理
WPF开发者必读:掌握多语言应用程序开发秘籍,带你玩转WPF国际化支持!
【8月更文挑战第31天】随着全球化的加速,开发多语言应用程序成为趋势。WPF作为一种强大的图形界面技术,提供了优秀的国际化支持,包括资源文件存储、本地化处理及用户界面元素本地化。本文将介绍WPF国际化的实现方法,通过示例代码展示如何创建和绑定资源文件,并设置应用程序语言环境,帮助开发者轻松实现多语言应用开发,满足不同地区用户的需求。
22 0
|
11天前
|
Java 开发者
Java编程中的异常处理机制探究
【8月更文挑战第31天】 在Java的世界中,异常处理是维护程序稳定性的重要工具。它像是一套精密的免疫系统,保护代码免受错误的侵袭,确保程序能够优雅地应对意外情况。本文将带你走进Java的异常处理机制,了解如何捕获和处理异常,以及自定义异常类的创建与应用,让你的代码更加健壮,运行更加顺畅。