Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存总分配了不同大小的内存空间,Java的数据类型结构图如下:
下表是基本数据类型的一些相关信息:
其中范围可以查阅API中相对应类的MAX_VALUE与MIN_VALUE常量值,
初始值见http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
从表中可以看到每一种类型的数据类型表示的范围是不一样的,换种说法可以说是精度不一样,所以我们在对不同数据类型进行运算时就涉及数据类型转换的问题,就像现在我们手上有美元与人民币两种货币,现在想要计算一下手上总共有多少钱,这时我们就需要先把美元兑换成人民币(或者人民币转换成美元),这样我们才能得出想要的结果,如果我们想要得到较为精确地结果,则这时最佳的做法是把手上的美元兑换成人民币,假设美元:人民币=1:6,现在有9美元与13块人民币,则共有人民币=6*9+13=67,而如果以美元为单位的话,这时则有美元=9+13/6≈11.17,这个结果在一定程度上已经损失了精度,与之类似,我们在对Java的基本数据类型进行运算的时候,计算机会自动把低精度类型的数据自动转成高精度的数据类型(低精度能表示的数据范围比高精度的小,可以理解成在内存中占用的比特位少),现在来分析一下'a'+1的结果是多少呢?首先'a'是一个字符数据类型,而1是一个整型数据类型,字符型占16个bit位,整型占32个bit位,计算机就会把字符型“看成”是32位的整型值,这时我们就会有一个疑问了,‘a'是个字符,那么如何跟1这个整数做加法运算呢,实际上在计算机中’a'表现形式是以二进制存在的,Java中有句非常出名的话叫“一切皆对象”,套用在这边可以说计算机中的所有数据“一切皆01”,为了能让计算机识别我们在键盘上敲击的字符,计算机的发明者就制订一张与键盘上相对应的码表--ASCII表(我们的汉字有专门的码表),从ASCII码表中我们可以得知字符a所对应的数值是97,然后97再转成二进制与1的二进制进行相加,相加后的结果再转化成十进制98返回回来。
实际上在对byte型、short型与char型的值进行运算时会被自动提升为int型的值。如果一个操作数是long型,计算结果就是long型; 如果一个操作数是float型,计算结果就是float型; 如果一个操作数是double型,计算结果就是double型。由于每种数据类型都定义范围,所以如果我们定义byte b = 128,则编译器会报错(在IDE中如Eclipse会自动提示错误),因为byte的范围是-128~127,而128不在该范围内。 其他的类型在定义的时候也需要避免这个问题,在实际中,根据需求选用合适的数据类型,可以减少内存占用空间。
上面讲到的是自动类型提升,有时我们需要根据实际情况对数据类型进行强制转换,比如说进行数学考试的时候,有时候最后一题为附加题(假如分数为10分),现在这个分数记入总分,但是不用于学生的成绩排名,则这时我们定义分数就用byte类型,已知一个学生的成绩为89分,则有byte score = 89;而这名学生的附加分数为6分,则有score = (byte)(socre + 6),由于socre + 6 = 95并未超出byte范围,所以可以进行强制转换,如果超过得到的结果则会与预期的不同。