Java程序设计教程
上QQ阅读APP看书,第一时间看更新

1.3 Java的数据类型

任何一个计算机应用程序都是在不断的数据分析、处理中实现其功能的。所以,在真正开始设计Java应用程序之前,首先需要建立Java使用的各种数据类型的概念。

计算机程序运行时的主要工作实际上是进行一系列各类数据的读取、分析、处理和输出。这些数据在程序运行过程中需要存储在计算机内存中,并以变量或常量的形式进行管理。

为了准确地为各类数据分配所需的内存空间并提供合理的运算方法,就需要将数据分为不同的类型。每种类型的数据均被预定义了能够占用的存储容量(字节数),这就意味着任何一种类型的数据都被规定了可取值的范围,超出这个范围将会导致数据的“溢出”。

1.3.1 基本类型和引用类型

Java将数据分为基本类型和引用类型两大类。基本类型中主要包括整型、浮点型、布尔型和字符型。引用类型中最常用的有字符串型、数组、类的对象等。本节仅介绍基本类型和引用类型中的字符串类型,其他将在后续章节中介绍。

1.基本类型

基本类型数据主要包括数值型(整型、浮点型)、字符型和布尔型3大类。

(1)整型

整型数据包括正整数、负整数和零。Java中将整数分为byte(字节型)、short(短整型)、int(整型)和long(长整型)4种类型,每种类型可占用不同大小的存储空间。不同的整型表示的数值范围也不同,这为开发人员根据实际需要进行灵活选择提供了方便,同时设置适当的类型对节约系统资源,提高程序运行效率也是十分重要的。常用整数类型、占用的存储空间及取值范围见表1-1。

表1-1 整型数据及取值范围

需要说明以下两点:

1)从表1-1中可以看出,就算是数值范围最大的long类型,也会有无法表示的超小或超大的整数。此时,应当使用Java提供的BigInteger类来处理数据。

2)Java将一个整数默认为int类型。若需要将一个整数表示为long类型时,则需要在数字的后面加上l或L(大写或小写的L)。

(2)浮点型

浮点型用于表示一个实数(既有整数又有小数的数),浮点型数据分为标准计数法(如3.0、4.156等)和科学计数法(如123.45表示为1.2345E+2)两种。

Java根据所需数值范围不同将浮点型数据分为float(单精度)和double(双精度)两种类型,它们占用的字节数和取值范围见表1-2。

表1-2 浮点型数据及取值范围

需要说明以下两点:

1)无论是float还是double都是一种近似数据。其中,float型最多能有7位有效数字,能保证的精度为6位,也就是说float的精度为6~7位有效数字;double类型最多能拥有16位有效数字,能保证的精度为15位,也就是说double的精度为15~16位。在使用浮点数进行高精度计算时应注意上述问题。例如,下列语句执行后的输出结果不是2.7,而是2.6999999999999997。

若需要高精度的计算,可使用Java提供的BigDecimal类。

2)Java将一个浮点数默认为double类型,若希望表示一个float类型数值,则应在数值的后面加上一个f或F。

(3)布尔型

布尔型(boolean)也称为逻辑型,用来表示一个布尔值。布尔型数据的取值只能是true(真)或false(假),占用1个字节的存储空间,通常用来表示一个关系表达式(如a>b)或逻辑表达式(如a>b&a<c)的运算结果。

(4)字符型

字符型(char)用来存储单个字符,占用两个字节的存储空间。Java语言中的字符采用的是Unicode字符集编码方案,每个字符占用两个字节的存储空间(16位无符号整数),共包含有65536个字符。由于Unicode字符集支持英文、中文等多国文字,所以也被称为“万国码”。在Java中Unicode码用“\uxxxx”表示,前面的“\u”表示这是一个Unicode值,后面xxxx是4位16进制数。Unicode码的范围是\u0000~\uFFFF。

2.String类型

前面介绍过的基本数据类型在计算机内存中保存的是数值本身,而引用数据类型在内存中存储的则是数值的内存地址,它往往由多个基本数据组成。因此,常将对引用数据类型的引用称为“对象引用”,引用数据类型也被称为复合数据类型,在有的程序设计语言中将其称为“指针”。引用数据类型中最常用的有字符串类型、数组和类的对象等。

字符串类型(String)表示一个由若干字符组成的字符序列。严格地讲,String是Java的一个预定义类,字符串类型数据实际上是String类的一个实例化对象中存储的数据。例如:

上面两条语句可以简化为:

1.3.2 变量与常量

对用户来说,变量是用来描述一条信息的名称,在变量中可以存储各种类型的信息。而对计算机来说变量代表一个存储地址,变量的类型决定了存储在变量中的数据的类型。简单地讲,变量就是在程序运行过程中,其值可以改变的数据。程序是通过变量的名称来访问相应内存空间的。

常量存储的是在程序运行中不能被修改的固定值。Java中常量与变量相同,也分为整型、浮点型、布尔型、字符型和字符串型。

在程序设计中使用变量与常量进行数据传递、数据读写等是最为基础的操作,正确理解和使用变量、常量是程序设计工作的重要技术之一。

1.标识符

标识符是用来表示变量名、类名、方法名、数组名和文件名的有效字符序列。开发人员可依据相应的规范自行决定要使用的标识符。关于标识符的命名应遵循如下一些规定。

1)标识符可以由大小写字母、数字、下划线、符号$等组合而成。

2)标识符只能以字母、下划线、$开头,不能以数字开头。标识符中不能包含空格、小数点或其他特殊字符。

3)标识符不能是Java的关键字(已被Java占用并赋予特定含义的字符串),如int、double、String等不能用作标识符。

4)标识符中变量名、方法名、数组名使用第一个单词全部小写后面的每个单词首字母大写(如age、myName等);类名每个单词的首字母都要大写(如Student、MyClass等)。

5)标识符应该能够标识事物的特性。例如,用于存储用户名的字符串变量可使用userName来命名。

2.声明变量

变量总是和变量名联系在一起的,所以要使用变量,必须为变量命名。在Java中,命名变量的过程称为“声明”。

声明变量就是把存储数据的类型告诉计算机,以便为其安排需要的内存空间。同时将变量名和安排的内存地址关联,以方便数据的读写。变量的数据类型可以对应所有合法的数据类型。声明变量最简单的语法格式如下:

例如:

需要注意以下两点:

1)变量必须“先声明,后使用”。直接使用没有进行类型和名称声明的变量时,将出现未找到变量的错误。为了尽量避免这类错误,Java IDE软件都具有将已声明的变量自动添加到智能感知提示列表中的功能。

2)对于已声明的,较长或拼写复杂的变量名,最好先输入首字母或前面若干个字母,再用上下光标键从智能感知供选列表中选择需要的名称,最后使用“.”号、空格键或〈Enter〉键将其输入,这样可以有效地避免拼写错误。

3.为变量赋值

变量声明后没有赋值或需要重新赋予新值时可使用如下所示的语句,语句中的“=”称为赋值运算符。

为变量赋值时可以使用直接量,也可以使用变量表达式。例如:

若需要为多个变量赋予相同值时可以使用如下所示的语句。

需要说明以下两点:

1)赋值号“=”与数学中的等号具有相同的外观,但它们的含义是完全不同的。例如,在数学中x=12与12=x均正确,但在赋值语句中x=12是正确的,而12=x就是错误的,因为语法格式要求变量只能出现在赋值表达式的左边。

2)在程序中使用已声明但未赋值的变量将导致错误。例如,下列语句是错误的。

4.变量的作用域

变量的作用域是指变量的可见范围,也可以理解为变量的有效范围。Java将变量分成全局变量和局部变量两大类。

(1)全局变量

全局变量主要包括实例变量(也称为普通全局变量)和静态变量。

1)实例变量和静态变量都需要声明在类中,且不能包含在任何一个方法中。

2)静态变量需要使用static关键字来声明。

需要注意的是,无论全局变量的声明语句写在什么位置,它的作用域都是整个类。

(2)局部变量

局部变量是指在某方法中或某块语句结构(如if、for、while、switch等)中声明的变量。局部变量的作用域限定在所在方法或块语句结构内,也就是变量声明语句所在的一对大括号内。

例如,下列语句中x为静态变量,y为实例变量,a、b为局部变量。

5.常量与常用转义符

(1)声明和使用常量

Java中使用final修饰符来声明常量,其语法格式如下:

例如:

常量的使用方法与变量相同,可以使用常量名来表示常量值。例如:

在程序中使用常量有以下3个优点。

1)不必反复输入同一个数据,这在数据本身较复杂时更能显示出其优势。

2)如果必须修改常量的值时,仅需在源代码中修改一个地方。

3)用一个描述性名称命名常量,可以提高代码的可读性。

(2)常用转义符

转义符用来表示一些切实存在,但无法以常规的方式显示的特殊符号。如换行、回车、Tab等。所有转义符都用符号反斜杠“\”开头,后面跟一个特定的字母表示。常用转义符及说明见表1-3。

表1-3 常用转义符及说明

字符串中需要使用单引号“'”、双引号“"”或反斜杠“\”时,为了避免二义性就需要使用转义符来表示。例如,下列语句输出为:他说:"Java是很有用的",并在结尾输出一个回车符。

1.3.3 数据类型的转换

在处理数据的过程中,经常需要将一种数据类型转换为另一种数据类型。例如:

要想得到带有小数的计算结果,就需要将a和b转换成浮点型数据后再执行a/b的操作。在Java中,数据类型的转换分为“隐式转换”与“显式转换”两种。

1.隐式转换

(1)隐式转换的概念

隐式转换是系统自动执行的数据类型转换。隐式转换的基本原则有两个:首先,原类型与目标类型是兼容的;再者,原类型的数值范围小,目标类型的数值范围大。例如:

(2)char类型隐式转换为数值

Java允许将char(字符)类型的数据隐式转换为数值范围在短整型short及以上的数值类型。例如:

之所以允许将字符型数据隐式转换为整数,是因为char类型的数据在内存中保存的实质是整型数据,只是从意义上代表的是Unicode字符集中的一个字符。

(3)数值隐式转换为字符串

当一个字符串与一个数值型数据进行“+”运算时,Java会首先将数值型数据转换成字符串,而后再与原字符串连接。例如:

2.显式转换

显式转换也称为强制转换,是在代码中明确指示将某一类型的数据转换为另一种类型。显式转换语句的一般格式如下:

例如:

实际上,显式转换包括了所有的隐式转换,也就是说把任何隐式转换写成显式转换的形式都是允许的。与隐式转换相同,进行显式转换也要求原类型与目标类型兼容;不同的是若将数据范围大的类型转换成数值范围小的类型时,可能出现精度下降的情况。例如:

如果希望将一个数字字符串转换成某种数值类型,可使用如下所示的显式转换方法。

上面代码中Integer是int类型的包装类,Double是double类型的包装类。它们用于将基本类型的int或double转换成对应的引用类型,以方便调用包装类提供的方法进行类型转换或进行其他操作。

1.3.4 字符串的常用操作方法

Java的String类为处理字符串数据提供了大量实用的方法,通过这些方法可以实现对字符串进行测长度、取子串、比较等操作。关于字符串常用的操作方法见表1-4。

表1-4 String对象的常用方法

1.3.5 常用数学方法和随机数

Java在Math类中预定义了两个常量和大量用于数学计算(如三角函数、平方根、幂运算、生成随机数等)的方法,这些常量和方法的说明见表1-5。

表1-5 数学类常用属性与方法

除了上述常用的数学运算方法外,Math类还提供了一个用于产生随机数的random()方法。该方法可以产生一个大于等于0.0,小于1.0的double类型的随机数。

如果希望产生一个a~b的随机整数(包括a和b),可使用如下所示的语句格式。

例如,下列语句用于产生一个10~99的随机整数(包括10和99)。