Java中的数据类型

Java是一种强类型语言。这就意味着必须为每一个变量声明一种类型。在Java中,一共8种基本类型(primitive type),其中有4种整型、2种浮点类型、1种字符类型和一种用于表示真值的boolean类型。

Java有一个能够表示任意精度的算术包,通常称为“大数”(big number)。虽然被称为大数,但它并不是一种基本Java类型,而是一个Java对象。

整型

整型用于表示没有小数部分的数值,允许是负数。Java提供了4种整型:

类型存储需求取值范围
int4字节-2147483648~2147483647
short2字节-32768~32767
long8字节-9223372036854775808~9223372036854775807
byte1字节-128~127

在通常情况下,int类型最常用。但如果想要表示整个地球的居住人口,就需要使用long类型了。byte和short类型主要用于特定的应用场合,例如,底层文件处理或者存储空间很宝贵时的大数组。

在Java中,整型的范围与运行Java代码的机器无关。这就解决了软件从一个平台移植到另一个平台,或者在同一个平台中的不同操作系统之间进行移植给程序员带来的诸多问题。

长整型数值有一个后缀L或l(如4000000000L)。十六进制数值有一个前缀0x或0X(如0xCAFE)。八进制有一个前缀0,例如,010对应十进制中的8。很显然,八进制表示法比较容易混淆,所以建议最好不要使用八进制常数。

从Java 7开始,加上前缀0b或0B就可以写二进制数。例如,0b1001就是9。另外,同样从Java 7开始,还可以为数字字面量加下划线,如用1_000_000表示100万。这些下划线只是为了让人更易读。Java编译器会去除这些下划线。

注意,Java没有任何无符号(unsigned)形式的int、long、short或byte类型。

如果要使用不可能为负的整数值而且确实需要额外的一位(bit),也可以把有符号整数值解释为无符号数,但是要非常仔细。例如,一个byte值b可以不表示范围-128~127,如果你想表示0到255的范围,也可以存储在一个byte中。基于二进制算术运算的性质,只要不溢出,加法、减法和乘法都能正常计算。但对于其他运算,需要调用 Byte.toUnsignedInt(b) 来得到一个0到255的int值,然后处理这个整数值,再把它转换回byte。Integer和Long类都提供了处理无符号除法和求余数的方法。

public class test {

    public static void main(String[] args) {
        Byte b = -1;
        int a = Byte.toUnsignedInt(b);
        System.out.println(a);
        System.out.println((byte)a);
    }

}

输出:
255
-1

浮点类型

浮点类型用于表示有小数部分的数值。在Java中有两种浮点类型:

类型存储需求取值范围
float4字节大约 ± 3.40282347 E + 38 F \pm 3.40282347E+38F ±3.40282347E+38F(有效位数为6~7位)
double8字节大约 ± 1.79769313486231570 E + 308 \pm 1.79769313486231570E+308 ±1.79769313486231570E+308(有效位数为15位)

double表示这种类型的数值精度是float类型的两倍(有人称之为双精度数值)。在很多情况下,float类型的精度(6~7位有效数字)并不能满足需求。实际上,只有很少的情况适合使用float类型,例如,需要单精度数的库,或者需要存储大量数据时。

float类型的数值有一个后缀F或f(例如3.14F)。没有后缀F的浮点数值(如3.14)总是默认为double类型。当然也可以在浮点数值后面添加后缀D或d。

所有的浮点数值计算都遵循IEEE 754规范。具体来说,下面是用于表示溢出和出错情况的三个特殊的浮点数值:

  • 正无穷大
  • 负无穷大
  • NaN(不是一个数字)
    例如,一个正整数除以0的结果为正无穷大。计算0/0或者负数的平方根结果为NaN。

常量Double.POSITIVE_INFINITY、Double.NEGATIVE_INFINITY和Double.NaN分别表示这三个特殊的值,但实际应用中很少遇到。特别要说明的是,不能如下检测一个特定值是否等于Double.NaN:
if (x == Double.NaN) // is never true
所有的“非数值”的值都认为是不相同的。不过,可以如下使用Double.isNaN方法来判断:
if (Double.isNaN(x)) // check whether x is “not a number”

浮点数值不适用于无法接受舍入误差的金融计算。例如,命令System.out.println(2.0-1.1)将打印出0.8999999999999999,而不是人们期望的0.9。这种舍入误差的主要原因是浮点数值采用二进制系统表示,而在二进制系统中无法精确地表示分数1/10。这就好像十进制无法精确表示分数1/3一样。如果在数值计算中不允许有任何舍入误差,就应该使用BigDecimal类。

char类型

char类型原本用于表示单个字符。不过,现在情况已经有所变化。如今,有些Unicode字符可以用一个char值描述,另外一些Unicode字符则需要两个char值。

char类型的字面量要用单引号括起来。例如:'A’是编码值为65的字符常量。它与"A"不同,"A"是包含一个字符A的字符串。char类型的值可以表示为十六进制值,其范围从\u0000到\uFFFF。

除了转义序列\u之外,还有一些用于表示特殊字符的转义序列,请参看下表。所有这些转义序列都可以出现在加引号的字符字面量或字符串中。转义序列\u还可以出现在加引号的字符常量或字符串之外(而其他所有转义序列不可以)。例如:

public static void main(String \u005B \u005D args)

就完全符合语法规则,\u005B和\u005D分别是[和]的编码。

转义序列名称Unicode值
\b退格\u0008
\t制表\u0009
\n换行\u000a
\r回车\u000d
"双引号\u0022
单引号\u0027
\反斜杠\u005c

Unicode转义序列会在解析代码之前得到一个处理。例如,“\u0022+\u0022”并不是一个由引号包围加号构成的字符串。实际上,\u0022会在解析之前转换为",这会得到""+"",也就是一个空串。
更隐秘地,一定要当心注释中的\u。注释
// \u000A is a newline
会产生一个语法错误,一位读程序时\u00A0会替换为一个换行符。类似地,下面这个注释
// look inside c:\users
也会产生一个语法错误,因为\u后面并没有跟着4个十六进制数。

boolean类型

boolean类型有两个值:false和true,用来判定逻辑条件。整型值和布尔值之间不能进行相互转换。

数值类型之间的转换

在这里插入图片描述
图中有6个实线箭头,表示无信息丢失的转换;另外有3个虚线箭头,表示可能有精度损失的转换。

当用一个二元运算符连接两个值时(例如n+f,n是整数,f是浮点数),先要将两个操作数转换为同一种类型,然后再进行计算。

  • 如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型。
  • 否则,如果其中一个操作数是float类型,另一个操作数将会转换为float类型。
  • 否则,如果其中一个操作数是long类型,另一个操作数将会转换为long类型。
  • 否则,两个操作数都将被转换为int类型。

强制类型转换

强制类型转换可能会损失一些信息。强制类型转换的语法格式是在圆括号中给出想要转换的目标类型,后面紧跟着待转换的变量名。

如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下,这种操作更有用),那就需要使用Math.round方法:

double x = 9.991;
int nx = (int) Math.round(x); //nx为10

当调用round的时候,仍然需要使用强制类型转换。其原因是round方法返回的结果为long类型,由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能将long类型转换为int类型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值