Java语言程序设计(第3版)
上QQ阅读APP看书,第一时间看更新

2.2 数据类型

在程序设计中,数据是程序的必要组成部分,也是程序处理的对象。不同的数据有不同的类型,不同的数据类型有不同的数据结构、不同的存储方式,并且参与的运算也不同。

2.2.1 数据类型概述

Java语言的数据类型可分为基本数据类型(primitive data type)和引用数据类型(reference data type),如表2-1所示。

本节主要讨论基本数据类型,引用数据类型在后面的章节介绍。

从表2-1中可以看到,Java共有8种基本数据类型。基本数据类型在内存中所占的位数是固定的,不依赖于所用的机器,这也正是Java跨平台的体现。各种基本数据类型在内存中所占位数及取值范围如表2-2所示。

表2-1 Java语言的数据类型

表2-2 Java基本数据类型

2.2.2 字面值和常量

字面值(literals)是某种类型值的表示形式,如100是int类型的字面值。字面值有三种类型:基本类型的字面值、字符串字面值以及null字面值。基本类型的字面值有4种类型:整数型、浮点型、布尔型、字符型。例如,123、−789为int型字面值;3.456、2e3为double型字面值;true、false为布尔型字面值;'g'、'我'为字符字面值。字符串字面值是用双引号定界的字符序列,如"Hello"是一个字符串字面值。

常量(constant)是在程序运行过程中,其值不能被改变的量。常量实际上是一个由final关键字修饰的变量,一旦为其赋值,其值在程序运行中就不能被改变。例如,下面定义了几个常量:

常量可以在声明的同时赋值,也可以声明后赋值。不管哪种情况,一旦赋值便不允许修改。常量的命名应该全部大写并用下画线将词分隔开。

2.2.3 整数类型

Java语言提供了4种整数类型,分别是byte型(字节型)、short型(短整型)、int型(整型)和long型(长整型)。这些整数类型都是有符号数,可以为正值或负值。每种类型的整数在内存中占的位数不同,因此能够表示的数的范围也不同。

注意:不要把整数类型的宽度理解成实际机器的存储空间,一个byte型的数据可能使用32位存储。

Java的整型字面量有4种表示方法。

(1)十进制数,如0、257、−365。

(2)二进制数,是以0b或0B开头的数,如0B00101010表示十进制数42。

(3)八进制数,是以0开头的数,如0124表示十进制数84,−012表示十进制数−10。

(4)十六进制数,是以0x或0X开头的整数,如0x124表示十进制数292。

注意:整型字面值具有int类型,在内存中占32位。若要表示long型字面值,可以在后面加上l或L,如125L,它在内存占64位。

Java的整型变量使用byte、short、int、long等声明,下面是几个整型变量的定义。

注意下面代码的输出:

注意:在为变量赋值时,不能超出该数据类型所允许的范围,否则会发生编译错误。

编译错误说明类型不匹配,不能将一个int型的值转换成byte型值。因为200超出了byte型数据的范围(−128~127),因此编译器拒绝编译。

在表示较大的整数时,需要用到长整型long。例如,下面程序计算一光年的距离。

程序2.2 LightYear.java

程序运行结果如下:

如果把该程序的变量seconds和distance的类型声明为int类型,编译不会出现错误,但结果不正确。

2.2.4 浮点类型

浮点类型的数就是通常所说的实数。在Java中有两种浮点类型的数据:float型和double型。这两种类型的数据在内存中所占的位数不同,float型占32位,double型占64位。因此,通常将float型称为单精度浮点型,将double型称为双精度浮点型。它们符合IEEE 754标准。

浮点型字面值有两种表示方法。

(1)十进制数形式,由数字和小数点组成,且必须有小数点,如0.256、.345、256.、256.0等。

(2)科学记数法形式,如256e3、256e−3,它们分别表示256×103和256×10−3。e之前必须有数字,e后面的指数必须为整数。

浮点型变量的定义使用float和double关键字,如下两行分别声明了两个浮点型变量pi和d:

代码运行结果为:

注意:浮点型字面值默认是double型数据。如果表示float型字面值数据,必须在后面加上F或f,double型数据也可加D或d。

浮点数运算结果可能溢出,但不会因溢出而导致异常。如果下溢,则结果为0;如果上溢,结果为正无穷大或负无穷大(显示为Infinity或−Infinity)。此外,若出现没有数学意义的结果,则用NaN(Not a Number)表示,如0.0/0.0的结果为NaN。这些常量已在基本数据类型包装类中定义。

浮点数计算可能存在舍入误差,因此,浮点数不适合做财务计算,而在财务计算中的舍入误差是不能接受的。例如,下面命令的输出结果是0.8999999999999999,而不是所期望的0.9。

这样的舍入误差是因为浮点数在计算机中使用二进制表示导致的。分数1/10没有精确的二进制表示,就像1/3在十进制系统无法精确表示一样。如果需要精确而无舍入误差的数字计算,可以使用BigDecimal类。8.3.7节介绍了该类。

如果一个数值字面值太长,读起来会比较困难。因此,从Java 7开始,对数值型字面值的表示可以使用下画线(_)将一些数字进行分组,这可以增强代码的可读性。下画线可以用在浮点型数和整型数(包括二进制、八进制、十六进制和十进制)的表示中。下面是一些使用下画线的例子:

在数值字面值中使用下画线对数据的内部表示和显示没有影响。例如,如果用long型表示一个信用卡号,这个值在内部仍使用long型数表示,显示也是整数。

注意:在数值字面值中使用下画线只是提高代码的可读性,编译器将忽略所有的下画线。另外,下画线不能放在数值的最前面和最后面,也不能放在浮点数小数点的前后。

2.2.5 字符类型

字符是程序中可以出现的任何单个符号。字符在计算机内部是由一组0和1的序列表示的。将字符转化为其二进制表示的过程称为编码(encoding)。字符有多种不同的编码方法,编码方案定义了字符如何编码。大多数计算机采用ASCII码,它是表示所有大小写字母、数字、标点符号和控制字符的7位编码方案。

与ASCII码不同,Java语言使用Unicode(统一码)为字符编码,它是由Unicode Consortium建立的一种编码方案。Unicode字符集最初使用两个字节(16位)为字符编码,这样就可表示65 536个字符。新版Unicode 4.0标准使用UTF-16为字符编码,可以表示更多的字符,它可以表示世界各国的语言符号,包括希腊语、阿拉伯语、日语以及汉语等。ASCII码字符集是Unicode字符集的子集。

字符型字面值用单引号将字符括起来,大多数可见的字符都可用这种方式表示,如'a'、'@'、'我'等。对于不能用单引号直接括起来的符号,需要使用转义序列来表示。表示方法是用反斜杠(\)表示转义,如'\n'表示换行、'\t'表示水平制表符,常用的转义序列如表2-3所示。

在Java程序中,还可以使用反斜杠加3位八进制数表示字符,格式为'\ddd',如'\141'表示字符'a'。也可以使用反斜杠加4位十六进制数表示字符,格式为'\uxxxx'。例如,'\u0062'表示字符'b','\u4F60'和'\u597D'分别表示中文的“你”和“好”。任何的Unicode字符都可用这种方式表示。

表2-3 常见的转义字符序列

字符型变量使用char定义,在内存中占16位,表示的数据是0~65 535。字符型变量的定义如:

Java字符型数据实际上是int型数据的一个子集,因此可以将一个正整数的值赋给字符型变量,只要在0~65 535即可,但输出仍然是字符。

字符型数据可以与其他数值型数据混合运算。一般情况下,char类型的数据可直接转换为int类型的数据,而int类型的数据转换成char类型的数据需要强制转换。

2.2.6 布尔类型

布尔型数据用来表示逻辑真或逻辑假。布尔型常量很简单,只有两个值true和false,分别用来表示逻辑真和逻辑假。

布尔型变量使用boolean关键字声明。例如,下面语句声明了布尔型变量t并为其赋初值true:

所有关系表达式的返回值都是布尔型的数据,如表达式10 < 9的结果为false。布尔型数据也经常用于选择结构和循环结构的条件中,请参阅3.1节和3.2节的内容。

注意:与C/C++语言不同,Java语言的布尔型数据不能与数值数据相互转换,即false和true不对应于0和非0的整数值。

下面程序演示了字符型数据和布尔型数据的使用。

程序2.3 CharBoolDemo.java

程序运行结果为:

语句“b = ch1 == ch2;”是将ch1和ch2的比较结果赋给变量b,由于ch1与ch2的值不相等,因此输出b的值为false。语句“ch2++;”说明字符型数据可以完成整数运算,但运算结果不能超出char类型的范围。如果ch2的初值是65 536,程序会产生编译错误。

2.2.7 字符串类型

在Java程序中,经常要使用字符串类型。字符串是字符序列,不属于基本数据类型,是一种引用类型。字符串在Java中是通过String类实现的。可以使用String声明和创建一个字符串对象。可以通过双引号定界符创建一个字符串字面值。例如:

一个字符串字面值不能分成两行来写。例如,下面代码会产生编译错误:

对于较长的字符串,可以使用加号将两个字符串连接:

还可以将一个String和一个基本类型或另一个对象连接在一起。例如,下面这行代码就是字符串常量和一个int型变量及double型变量连接。