今天我要说得是关于Java类型之间相互转换的事。
对于Java基本之间的转换来说,大致分为两种,分别是:自动类型转换和强制类型转换。
自动类型转换
所谓自动类型转换就是指两种类型转换时无需附加额外的操作,直接将一种类型的值赋给另一种类型的值即可。下面将分别讨论基本数据类型之间的自动转换和引用数据类型之间的自动类型转换。
- 基本类型
对于基本类型来说,只有四种整数、两种浮点数和字符之间可以发生自动类型转换,从表示范围小的数向表示范围大的自动转换。它们的表示范围从小到大分别为:byte < short < int < long < float < double和char < int < long < float < double。
这里需要强调的是,char虽然叫字符类型,但是其在内存中表示的时候依然是一个整数,也就是该字符对应的Unicode编码。
byte,short, int,long,float,double自动转换例子如下图所示:
char,int,long,float,double自动类型转换的例子如下图所示:
需要强调的是,我为了展示方便,将多条语句塞在了一行里,从语法上讲允许,但是在实际开发中,还是要尽量避免。
- 引用类型
对于引用数据类型来说,只有两种类型之间存在直接或间接的继承关系时候才能发生自动类型转换,从子类型向父类型自动转换。
这里我以系统提供的Integer、Number、Object来进行演示。这里从父到子依次为:Object、Number、Integer。示例代码如下图所示:
强制类型转换
所谓强制类型转换是指,当两个类型之间无法进行自动类型转换,但依然存在类型转换的需求时,可以使用强制类型进行转换。同样的,强制类型转换也存在基本类型之间的强制转换和引用类型之间的强制类型。
- 基本类型
对于基本类型之间的强制类型转换而言,依然只能在除boolean类型之外的数据类型之间发生。只不过强制类型转换是将表示范围大的数据向表示范围小的类型进行转换。
byte,short, int,long,float,double之间的强制类型转换的示例如下图所示:
char,int,long,float,double强制类型转换的示例如下图所示:
虽然,强制类型转换在语法上是允许的,但还是要谨慎使用。因为是从表示范围大的数据类型向表示范围小的数据类型进行转换,所以在两种数据类型发生强制类型转换的时候,会发生部分数据的丢失,进而引发数据精度问题。
- 引用类型
对于引用数据类型之间的强制类型转换而言,同样的,也只能发生在存在直接或间接继承关系的类之间。如果两个数据类型不存在直接或间接的继承关系,则无法进行强制类型。同样的,我还是以Object、Number、Integer这三个类来进行引用数据类型之间的强制类型转换,其示例代码如下图所示:
需用说明的是,强制类型转换虽然在语法上允许,但还是要谨慎使用,与基本数据类型之间的强制类型转换不同的是,这里不会发生数据丢失,但是可能会发生类转换异常。比如下面的例子。
执行结果如下图所示:
这个很好理解。因为我声明的Object对象的实际数据类型为Double。强制转换为Number时并不会有任何问题,因此Double可以被当做Number使用。但是,Integer和Double并不存在直接或间接的继承关系,所以试图将Double类型转换为Integer类型时,就会发生如上图所示的异常,也即类型转换异常。
表达式类型提升
所谓表达式类型提升是指,当一个算术表达式中包含多个基本数据类型时(不包括boolean类型),该表达式的所产生的值会自动转换为这些基本数据类型中表示范围最大的那种数据类型,也就是该算术表达式的数据类型发生了提升。
下面我将给出一个例子来简单说明一下,示例代码如下图所示:
此外还存在一种特例就是,如果表达式中存在字符串的时候,此时的表达式就不是算术运算表达式,而是字符串拼接。需要强调的是,如果一个表达式中存在字符串,那么该字符串后的部分的运算符只能为“+”,前面的与字符串相连的运算符也只能为“+”。这里的“+”代表的是字符串拼接,而非算术运算的加。
下面我将给出一个例子来进行说明,示例代码如下图所示:
自此,关于类型转换的问题就已经介绍完毕,希望大家都能掌握。