08-数据类型转换

nobility 发布于 2025-07-12 01-Java语言基础 2771 次阅读


数据类型转换

数据类型转换主要分为两大类:自动类型转换(隐式类型转换)和强制类型转换(显式类型转换),这些转换确保不同数据类型之间能够兼容并正确运算。

自动类型转换

自动类型转换指的是在不需要开发者手动干预的情况下,编译器自动将一种数据类型转换为另一种兼容且容量更大的数据类型。从而避免了类型不匹配的错误,保证了程序顺利运行。

转化条件

  1. 两种数据类型必须要兼容。
  2. 目标类型的容量或取值范围必须要大于源类型。

转换顺序(小容量到大容量)依次是:

  • byte -> short -> int -> long -> float -> double
  • char -> int -> long -> float -> double
  • 子类 -> 父类

其中,char 只能自动转换成 int 及更大容量的类型,但是 byteshort 不能自动转换为 char,并且 char 也不能自动转换为 byteshort

示例

byte 类型

// 虽然整数的默认字面量类型是 int,但是 10 并没有超出 byte 的范围,所以不会数据溢出,所以就不会报错
byte b = 10;
// 128 超出了 byte 的范围,所以会数据溢出,所以编译就会报错
byte b = 128;

// 如果使用的是变量 int,由于变量具有不确定性,所以直接将 int 类型转换到 byte 类型可能会溢出,所以编译时会报错
int i = 10;
byte b = i;

shortint 类型时与 byte 类型同理,就不举例了。

long 类型

// 整数的默认字面量类型是 int,然而 2147483648 超出了 int 的范围,所以编译就会报错
long l = 2147483648;
// 正确做法:在数字尾部添加 L 后缀,表示字面量类型是 long 类型
long l = 2147483648L;

floatdouble 类型

// 浮点数的默认字面量类型是 double,直接将 double 转换到 float 可能导致精度丢失,所以编译就会报错
float f = 3.14;
// 正确做法:在数字尾部添加 f 后缀,表示字面量类型是 float 类型
float f = 3.14f;

// 会在小数位补 0,转化结果为 3.0
float f = 3;

// long 换为 float 或 double 时,可能会丢失精度,但还是会自动转换
float f = 9223372036854775807L; // 9.223372E18
double d = 9223372036854775807L; // 9.223372036854776E18

char 类型

// char 自动转换为 int
int i = 'a';
// 虽然整数的默认字面量类型是 int,但是 97 并没有超出 char 的范围,所以不会数据溢出,所以就不会报错
char c = 97;

// 如果使用的是变量 int,由于变量具有不确定性,所以直接将 int 类型转换到 char 类型可能会溢出,所以编译时会报错
int i = 97;
char c = i;

// 如果使用的是变量 byte,看似没有精度丢失,但是底层还是会将 b 转换成 int 再赋给 c,所以编译时会报错
byte b = 97;
char c = b;

boolean 类型

// 与其他语言不通,Java 中 boolean 类型不能与其他基本数据类型相互转化,所以编译会报错
boolean b = 1;

String 类型

// 如果有字符串类型参与运算时,会自动调用其 toString() 方法,拼接字符串
String str = "1" + 1;

强制类型转换

强制类型转换是开发者显式的通过强制类型转换符,将一种数据类型强制转换为另一种数据类型的方法。

一般发生在:

  • 需要将容量较大的类型转为容量较小的类型时。
  • 需要将浮点类型转为整数类型时。
  • 需要将父类转子类时。

语法格式为:

目标类型 变量名 = (目标类型) 源变量名;

注意事项

  • 强制类型转换可能导致精度丢失。如果待转换的类型是浮点类型,并且小数部分有值,小数部分会被截断,而不是四舍五入。
  • 强制类型转换可能导致数据溢出。如果待转换的值超出目标类型的范围,结果会发生溢出,数据变得不可预测。
  • Java 中不能对 boolean 类型进行类型转换。
  • 引用类型类型之间的转换需要确保运行时对象的实际类型相互兼容,否则会抛出 ClassCastException

示例

double d = 9.99;
// 强制转换,结果为 9,小数部分会被截断
int i = (int) d;

int i = 300;
// 300 超出 byte 的范围,转换结果为 44,只保留后面 8 个比特位
byte b = (byte) i;

类型提升

在表达式运算中有不同数据类型参与运算时,会遵循从低级到高级类型转换原则,自动将所有操作数提升到表达式中数据范围最大的类型,以避免数据丢失,这称为类型提升。

表达式计算类型提升流程:

  • byteshortchar 都会转化为 int
  • 如果有 long 操作数,其他类型提升为 long
  • 如果有 float 操作数,其他类型提升为 float
  • 如果有 double 操作数,其他类型提升为 double

示例

// 因为表达式 b * 2 中的 2 是 int 类型,为了避免数据丢失,会进行类型提升
// 这时候的运算结果为 int 类型,直接将 int 类型直接赋值给 byte 时,编译就会报错
byte b = 10;
b = b * 2;
// 正确做法 1:使用强制类型转换
b = (byte)(b * 2);
// 正确做法 2:也可以使用用复合赋值运算符,因为复合赋值运算符会隐含强制转换
b *= 2; // 等价于 b = (byte)(b * 2);

shortcharlongfloatdouble 同理,就不举例了。

特别说明

  • boolean 类型只能表示 truefalse,不进行任何数值类型转换。
  • 字符类型 char 的转换比较特殊,只自动转换为整数类型。
  • 字符串与基本类型之间的转换需要调用相关包装类的方法,比如 Integer.parseInt("123") 将字符串转换为整数。
  • 基本类型和引用类型之间的转换需要使用包装类进行转换,比如 Integer.valueOf(1)
  • 如果有字符串类型参与运算时,会变成字符串拼接。
加油啊!即便没有转生到异世界,也要拿出真本事!!!\(`Δ’)/
最后更新于 2025-07-12