1. 类型转换

Java 中的类型转换

基本类型的变量(类型除外boolean)用于存储各种类型的数字。尽管变量的类型从未改变,但在某个地方您可以从一种类型转换为另一种类型。那个地方就是assignment

不同类型的变量可以相互赋值。执行此操作时,一种类型的变量值将转换为另一种类型的值并分配给第二个变量。在这方面,我们可以识别两种类型转换:扩大和缩小。

扩大就像将一个值从一个小篮子移动到一个大篮子:这个操作是无缝且无痛的。当您将一个值从一个大篮子移到一个小篮子时,就会发生变窄:可能没有足够的空间,您将不得不扔掉一些东西。

以下是按篮子大小排序的类型:

Java 2 中的类型转换


2. 扩大类型转换

通常需要将一种数值类型的变量赋值给另一种数值类型的变量。你是怎样做的?

Java 有 4 种整数类型:

类型 尺寸
byte 1 byte
short 2 bytes
int 4 bytes
long 8 bytes

存储在较小篮子中的变量总是可以分配给存储在较大篮子中的变量。

intshort变量byte可以很容易地分配给long变量。short变量byte可以赋值给int变量。并且byte变量可以赋值给short变量。

例子:

代码 描述
byte a = 5;
short b = a;
int c = a + b;
long d = c * c;
这段代码将编译得很好。

这种从较小类型到较大类型的转换称为扩大类型转换。

实数呢?

有了它们,一切都一样——大小很重要:

类型 尺寸
float 4 bytes
double 8 bytes

floatdouble变量可以毫无问题地赋值给变量。但是整数类型的事情更有趣。

您可以将任何整数变量分配给一个float变量。即使long是 8 字节长的类型。您可以将任何您想要的 - 任何整数变量或float变量 - 分配给一个double变量:

代码 笔记
long a = 1234567890;
float b = a;
double c = a;

b == 1.23456794E9
c == 1.23456789E9

请注意,由于缺少足够的有效数字,转换为实数类型可能会导致精度损失。

从整数转换为浮点数时,数字的低阶部分可能会被丢弃。但由于小数被理解为存储近似值,因此允许进行此类赋值操作。


3.缩小类型转换

那其他的可能性呢?如果需要longint变量赋值怎么办?

将变量想象成一个篮子。我们有各种大小的篮子:1、2、4 和 8 字节。将苹果从较小的篮子转移到较大的篮子不是问题。但是,当从较大的篮子转移到较小的篮子时,一些苹果可能会丢失。

这种从较大类型到较小类型的转换称为缩小类型转换。当执行这样的赋值操作时,数字的一部分可能根本不适合新变量,因此可能会被丢弃。

缩小类型时,我们必须明确告诉编译器我们没有犯错,我们是故意丢弃部分数字。类型转换运算符用于此。它是括号中的类型名称

在这种情况下,Java 编译器要求程序员指定类型转换运算符。一般来说,它看起来像这样:

(type) expression

例子:

代码 描述
long a = 1;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
每次都必须显式指示类型转换运算符

这里a等于1,也许类型转换运算符看起来有点矫枉过正。但如果a更大呢?

代码 描述
long a = 1000000;
int b = (int) a;
short c = (short) b;
byte d = (byte) c;
a == 1000000
b == 1000000
c == 16960
d == 64

一百万完全适合 along和 an int。但是给一个short变量赋值一百万时,前两个字节被丢弃,只保留最后两个字节。当分配给 a 时byte,唯一剩下的就是最后一个字节。

数字在内存中的排列方式:

类型 二进制符号 十进制表示法
int 0b 00000000 00001111 01000010 01000000 1000000
short 0b 01000010 01000000 16.960
byte 0b 01000000 64

char类型

Achar和 a 一样short,占用两个字节,但要将一个字节转换为另一个字节,您始终需要使用类型转换运算符。这里的问题是short类型是有符号的并且可以包含从-32,768到的值+32,767,但是类型是无符号的并且可以包含从到的char值。065,535

负数不能存储在 a 中char,但可以存储在 a 中short。并且 ashort不能存储大于的数字32,767,但是这样的数字可以存储在 a 中char


4. 表达式类型

如果在同一个表达式中使用不同类型的变量怎么办?从逻辑上讲,我们理解首先需要将它们转换为通用类型。但是哪一个?

当然是大一点的。

Java 总是转换为更大的类型。粗略地说,首先扩大其中一个类型,然后才使用相同类型的值执行操作。

如果表达式中包含anint和a long,则将a的值int转换为a long,然后才进行操作:

代码 描述
int a = 1;
long b = 2;
long c = a + b;
a将扩大到 along然后添加将发生。

浮点数字

如果表达式中涉及整数和浮点数(floatdouble),则将整数转换为浮点数(floatdouble),然后才执行运算。

如果操作涉及 afloat和 a double,则 thefloat将转换为 a double。这实际上是预期的。

惊喜

、和类型在相互交互时byte总是转换为。该类型被视为标准整数类型是有充分理由的。shortcharintint

如果将 a 乘以bytea short,您将得到 an int。如果将 a 乘以bytea byte,您将得到 an int。即使您添加 abyte和 a byte,您也会得到 an int

有几个原因。例子:

代码 描述
byte a = 110;
byte b = 120;
byte c = a * b;  // Error
110 * 12013,200,它略大于该byte类型的最大值:127
byte a = 110;
byte b = 120;
byte c = a + b; // Error
110 + 120230,它也略大于该byte类型的最大值:127

一般来说,一个8位(1字节)的数乘以一个8位(1字节)的数,得到一个占用16位(2字节)位的数

因此,所有具有小于 的整数类型的操作int总是立即转换为ints。这意味着如果您想将计算结果存储在类型小于 的变量中int,那么您将始终需要显式指定类型转换运算符。

例子:

代码 描述
byte a = 110;
byte b = 120;
byte c = (byte) (a * b);
byte * byte表达式将是一个int
byte a = 110;
byte b = 120;
byte c = (byte) (a + b);
byte + byte表达式将是一个int
byte a = 1;
byte b = (byte) (a + 1);
表达式byte + int将是 anint
字面值是 an int

5.一个重要的细微差别

类型转换运算符具有相当高的优先级。

这意味着如果表达式包含,例如,加法和类型转换运算符,则类型转换将在加法之前执行。

例子:

代码 描述
byte a = 1;
byte b = 2;
byte c = (byte) a * b;
类型转换运算符将仅应用于a已经是byte. 这段代码不会编译。
byte a = 1;
byte b = 2;
byte c = (byte) (a * b);
这是正确的方法。

如果要将整个表达式转换为特定类型,而不仅仅是表达式的一个组成部分,则将整个表达式括在括号中并将类型转换运算符放在前面。