“=” 操作符是使用最频繁的二元操作符,它能够把右边的操作元的赋值给左边操作元,并且以右边操作元的值作为运算结果。
同种类型的变量之间可以直接赋值,一个直接数可以直接赋值给它同类型的变量。
在同种类型的变量之间赋值时,不需要进行类型的转换。
当在不同类型的变量之间赋值时,或者将一个直接数赋值给与它不同类型的变量时,需要类型转换。
类型转换可以分为自动类型转换和强制类型转换两种。
自动转换是指运行时,Java 虚拟机自动把一种类型转换成另一种类型。
强制类型转换是指在程序中显式地进行类型转换。
在进行自动或强制类型转换时,被转换的变量本身没有任何变化。
基本数据类型转换
整型、浮点型、字符型数据可以进行混合运算。当类型不一致时,需要进行类型转换。
从低位类型到高位类型会进行自动转换。而从高位类型到低位类型需要进行强制类型转换。
boolean类型不能与其他的基本类型进行类型转换。(编译出错)
1、自动类型转换
表达式中不同类型的数据先自动转换为同一类型,然后进行计算。自动转换总是从地位类型到高位类型。这里的低位类型是指取值范围小的类型,高位类型是指取值范围大的类型。
规则:
(byte、char、short、int、long 或 float) op double -> double
(byte、char、short、int 或 long) op float -> float
(byte、char、short 或 int) op long -> long
(byte、char 或 short) op int -> int
(byte、char 或 short) op (byte、char 或 short) -> int
箭头左边表示参数与运算的数据类型,op 为操作符(如“+”、“-”、“*”、“/”等),箭头右边表示自动转换成的数据类型。
以上的规则说明:
当表达式中存在 double 类型的操作元时,把所有的操作元自动转换为 double 类型,表达式的值为 double 类型。
否则,当表达式中存在 float 类型的操作元时,把所有的操作元自动转换为 float 类型,表达式的值为 float 类型。
否则,当表达式中存在 long 类型的操作元时,把所有的操作元自动转换为 long 类型,表达式的值为 long 类型。
否则,把所有的操作元自动转换为 int 类型,表达式的值为 int 类型。
byte、short 和 char 类型的数据在如 “x++” 这样的一元运算中不自动转换类型。
在进行赋值运算时,也会进行地位到高位的自动类型转换。赋值运算的自动类型规则如下:
byte -> short -> int -> long -> float -> double
byte -> char -> int -> long -> float -> double
以上规则表明 byte 可以转换成 char、short、int、long、float 和 double 类型。short 可以转换成int、long、float 和 double 类型。
在给方法传递参数时,也会出现类型转换的情况,转换规则与赋值运算的自动转换规则相同。
2、强制类型转换
把高位类型赋值给低位类型,就必须进行强制类型转换,否则编译会出错。
short 和 char 类型的二进制的位数都是16,但 short 类型的范围是(-2的15次方~2的15次方减1),
char 的类型的范围是(0~2的16次方减去1),由于两者的取值范围不一致,在 short 变量和 char 变量之间的赋值总需要强制类型转换。
如果把 char 类型直接数赋给 short 类型变量,或者把 short 类型直接数赋值给 char 类型变量,那么只要直接数在变量的所属类型的取值范围内,就允许自动类型转换,否则需要强制类型转换。
在方法传递参数时,如果把高位类型传给低位类型,也需要强制类型站换。
强制类型转换有可能会导致数据溢出或精度下降,应该尽量避免使用强制类型转换。
eg:
(数据溢出)
int a = 256;
byte b = (byte)a; //数据溢出,变量的 b 的值为0
(精度丢失)
long l = (long)3.5101 //精度丢失,a 的取值为3
引用类型的类型转换
在引用类型的变量之间赋值时,子类给直接或间接父类赋值,会自动进行类型转换。父类给直接或间接子类赋值,需要强制类型转换。
对于引用类型变量,Java 编译器只根据变量被显式声明的类型去编译。在引用类型变量之间赋值时,“=” 操作符两边的变量被显式声明的类型必须是同种类型或有继承关系,即位于继承树的同一个分支上,否则编译出错。
在运行时,Java 虚拟机将根据引用变量实际引用的对象进行类型转换。