类型转换

Posted 乌龟王八蛋

tags:

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

类型转换

彼此兼容的类型之间,可以相互转换,兼容类型的大小比较则根据其内存空间判断

  1. 自动隐式 转换:无须声明,例如 int 类型变量接收 byte 类型变量
  2. 强制显式 转换:需要声明,例如 byte 类型变量接收 int 类型变量

对于原始数据类型之间的转换,需要注意参与其中的是 变量,还是字面量

对于字面量

以整数为例,其默认的字面量的类型是 int,此时以一个 byte 接收整数字面量

byte a = 100;

此时,发生的是自动隐式转换,100 未超出 byte 的取值,可以由 int 类型转为 byte 类型

但是,若 byte 接收的整数字面量超出了取值范围,例如 byte a = 200;

此刻,产生的就是强制显式转换,需要手动声明转换的类型 byte a = (byte) 200;

简单的理解为,当 byte 接收一个兼容类型的整数字面量时,存在两种情况

  • 未超出 byte 的取值:整数字面量由 int 自动隐式转换为 byte byte a = 100;
  • 已超出 byte 的取值:必须进行显式的强制转换 byte b = (byte) 200;

基于字面量在类型转换中的表现,需要注意一个问题

字面量默认 int 类型,若 long 类型变量接收了超出 int、小于 long 的整数字面量,必须后缀 L,提升该整数字面量的类型为 long

对于变量

在变量的数据类型转换中,则无须在意整型、浮点型的默认字面量类型

任何不同类型的变量之间,由大向小转换,都必须强制声明、强制转换

int a = 100;

byte b = (byte) a;

int 是三十二位二进制,byte 是八位二进制,转换的时候必然产生影响

数据溢出

在强制类型转换中,会导致一些令人疑惑的问题,这称为 数据溢出

最简单的例子就是,byte a = 400;

整数字面值的默认类型是 int,且赋值的字面量超出 byte 取值,无法自动转换

此刻,会发生如下情况

先理解四个概念

  • 符号位:二进制中,最高位作为符号位存在,0 为正,1 为负
  • 原码:数据的直接二进制表示,以十进制 127 为例,目标为八位二进制
    • + 127:01111111 原码
    • - 127:11111111 原码
  • 反码:在原码的基础上,全部取反,包括最高符号位
    • + 127:10000000 原码 -> 取反
    • - 127:00000000 原码 -> 取反
  • 补码:在反码的基础上,二进制数 加 1
    • + 127:10000001 取反 -> 补码
    • - 127:00000001 取反 -> 补码

数据溢出问题,是由二进制截断、符号位、原码、反码、补码组成

简单的理解:负数的二进制表现,是其对应正数的补码

  • 正数的二进制,就是它的原码表现形式
  • 负数的二进制,则是它对应的正数的补码表现形式

强制转换的最终结果,以字节型为例,它由八位二进制组成

若接收的数据的二进制表现已超出八位时,则对超出部分进行截断(注意最高位符号位)

此处,需要注意最高位,即符号位,正数可能在截断后转为负数,这也是为什么正数溢出后,会出现负数的原因

若二进制符号位为 0,则直接按原码,求出结果

若二进制符号位为 1,则当作补码,反推回原码,根据对应的正数,求出负数结果

负数的真正二进制表现,是其对应正数的补码表现

byte b = (byte) 400;
System.out.println(b);
/*
b 的最终结果为 -112
b 的二进制体现:110010000
截断为八位二进制:110010000 -> 10010000
112 的原码表现:01110000(八位二进制)
112 的补码表现:01110000 -> 取反 10001111 -> 补码 10010000
可以看出 + 112 的补码 = - 122 的原码
*/

小结

值得注意的是,浮点型中,存在精度的概念,double 字面量无法向下自动隐式转为 float

image

红色实线:内存存储自小向大转换,无损失,自动转换

蓝色虚线:内存存储自大向小转换,精度损失,强制转换

以上是关于类型转换的主要内容,如果未能解决你的问题,请参考以下文章

Android:片段无法转换为上下文[重复]

HTML Bookmarklet模板:将任何JavaScript代码片段转换为Bookmarklet

对象不能从 DBNull 转换为其他类型。

结合两个代码片段?将用户输入的 Youtube url 转换为嵌入 url,然后将 iframe src 替换为转换后的 url

片段无法转换为上下文

js常用代码片段(更新中)