1、本章学习目标:本章主要学习Java语言中的基本数据类型、运算符与表达式 掌握Java中的字符集、分隔符、标识符、关键字 掌握变量和常量的定义和初始化 掌握基本数据类型 掌握Java中数据类型的转换、运算符和表达式第二章第二章 数据类型与运算符数据类型与运算符第第1 1节节part字符 字符是各种文字和符号的总称,包括各国家文字、标点符号、图形符号、数字等。字符集是多个字符的集合,不同的字符集所包含的字符个数也不同。字符集种类较多,常见字符集有ASCII字符集、GB2312字符集和Unicode字符集。计算机要准确处理各种字符集文字,需要进行字符编码,以便计算机能够识别和存储各种文字。Unico
2、de字符集是由一个名为Unicode Consortium的非盈利机构制订的字符编码系统,支持各种不同语言的书面文本的转换、处理及显示。Unicode为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。Unicode支持UTF-8、UTF-16和UTF-32这三种字符编码方案,这三种方案的区别如表2-1所示。2.1.1字 符 集字符集 注意:注意:Java语言中基本所有输入元素都是采用ASCII字符集编码,而标识符、字符、字符串和注解则采用Unicode字符集编码。2.1.1字 符 集 Java中使用多种字符作为分隔符,用于辅助程序编写、阅读和理
3、解。这些分隔符可以分为两类:空白符:没有确定意义,但帮助编译器正确理解源程序,包括空格、回车、换行和制表符(Tab);普通分隔符:拥有确定含义,常用的普通分隔符如表2-2所示。2.1.2分隔符分隔符 需要需要注意的是:注意的是:任意两个相邻的标识符之间至少有一个分隔符,便于编译程序理解;空白符的数量多少没有区别,使用一个和多个空白符实现相同的分隔作用;分隔符不能相互替换,比如该用逗号的地方不能使用空白符。在各种编程语言中,通常要为程序中处理的各种变量、常量、方法、对象和类等起个名字作为标记,以便通过名字进行访问,这些名字统称标识符。Java中的标识符由字母、数字、下划线或美元符组成,且必须以字
4、母、下划线(_)或美元符($)开头。Java中标识符的命名规则如下:可以包含数字,但不能以数字开头;除下划线“_”和“$”符以外,不包含任何其他特殊字符,如空格;区分大小写,例如“abc”和“ABC”是两个不同的标识符;不能使用Java关键字。标识符可有任意长度。2.1.3标识符标识符以下是合法标识符的示例:以下是合法标识符的示例:varName _varName var_Name$varName _9Name以下是非法标识符的示例以下是非法标识符的示例:Var Name /包含空格9 varName /以数字开头a+b /加号“+”不是字母和数字,属于特殊字符,不是Java标识符组成元素 关
5、键字又叫保留字,是编程语言中事先定义的、有特别意义的标识符。关键字对编译器具有特殊的意义,用于表示一种数据类型或程序的结构等,关键字不能用于变量名、方法名、类名以及包名。Java中常用的关键字如表2-3所示。2.1.4关键字关键字第第2 2节节part变量和常量 变量是数据的基本存储形式,因Java是一种强类型的语言,所以每个变量都必须先声明后再使用。变量的定义包括变量类型和变量名,其定义的基本格式如下:数据类型 变量名=初始值;例如:定义整型变量 int a=1;/声明变量并赋初始值 其中,int是整型数据类型;a是变量名称;=是赋值运算符;1 是赋给变量的初始值。变量的声明与赋值也可以分开
6、,例如:int a;/声明变量 a=1;/给变量赋值 声明变量时,可以几个同一数据类型的变量同时声明,变量之间使用逗号“,”隔开,例如:int i,j,k;2.2.1变 量变量 常量是指一旦赋值之后其值不能再改变的变量。在Java语言中,使用final关键字来定义常量,其语法格式如下:final 数据类型 变量名=初始值;例如:定义常量 final double PI=3.1416;/声明了一个double类型的常量,初始化值为3.1416 final boolean IS_MAN=true;/声明了一个boolean类型的常量,初始化值为true 需要注意的是:在开发过程中常量名习惯采用全部
7、大写字母,如果名称中含有多个单词,则单词之间以“_”分隔。此外常量在定义时,需要对常量进行初始化,初始化后,在应用程序中就无法再对该常量赋值。2.2.2常 量常量第第3 3节节part数据类型 定义变量或常量时需要使用数据类型,Java的数据类型分为两大类:基本类型和引用类型。基本类型是一个单纯的数据类型,表示一个具体的数字、字符或布尔值。基本类型存放在内存的“栈”中,可以快速从栈中访问这些数据。引用类型是一个复杂的数据结构,是指向存储在内存的“堆”中数据的指针或引用(地址)。引用类型包括类、接口、数组和字符串等,由于要在运行时动态分配内存,所以其存取速度较慢。数据类型本节概述Java的基本数
8、据类型主要包括如下四类:整数类型:byte、short、int、long 浮点类型:float、double 字符类型:char 布尔类型:boolean2.3.1基本数据类型基本数据类型Java各种基本类型的大小和取值范围如表2-4所示。1.1.整型类型整型类型整数类型根据大小分为byte(字节型)、short(短整型)、int(整型)和long(长整型)四种,其中int是最常用的整数类型,因此通常情况下,直接给出一个整数值默认就是int类型。其中,在定义long类型的变量时,其常量后面需要用后缀l或L。例如:声明整型类型变量byte b=51;/声明字节型变量short s=34;/声明短
9、整型变量int i=100;/声明整型变量long m=12l;/声明长整型变量long n=23L;/声明长整型变量Java中整数值有4种表示方式:2.3.1基本数据类型 二进制:每个数据位上的值是0或1,二进制是整数在内存中的真实存在形式,从Java 7开始新增了对二进制整数的支持,二进制的整数以“0b”或“0B”开头。八进制:每个数据位上的值是0,1,2,3,4,5,6,7,其实八进制是由3位二进制数组成的,程序中八进制的整数以“0”开头。十进制:每个数据位上的值是0,1,2,3,4,5,6,7,8,9,十进制是生活中常用的数值表现形式,因此在程序中如无特殊指明,数值默认为十进制。十六进
10、制:每个数据位上的值是0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,与八进制类似,十六进制是由4位二进制数组成的,程序中十六进制的整数以“0 x”或“0X”开头。下述案例示例了整数类型的不同表示形式,代码如下所示。【代码2.1】IntValueExample.javapackage com;public class IntValueExample public static void main(String args)int a=0b1001;/二进制数 System.out.println(二进制数0b1001的值是:+a);int b=071;/八进制数 System.o
11、ut.println(八进制数071的值是:+b);int c=19;/十进制数 System.out.println(十进制数19的值是:+c);/Integer.toBinaryString()方法将一个整数以二进制形式输出 System.out.println(19的二进制表示是:+Integer.toBinaryString(c);int d=0 xFE;/十六进制数 System.out.println(十六进制数0 xFE的值是:+d);System.out.println(十六进制数0 xFE的二进制表示是+Integer.toBinaryString(d);int e=19;/
12、负数以补码形式存储 System.out.println(19的二进制表示是:+Integer.toBinaryString(e);2.3.1基本数据类型 上述代码中,Integer是int基本数据类型对应的封装类,该类提供一些对整数的一些常用静态方法,其中Integer.toBinaryString()方法可以将一个整数以二进制形式输出。2.3.1基本数据类型该程序运行结果如下所示:二进制数0b1001的值是:9 八进制数071的值是:57 十进制数19的值是:19 19的二进制表示是:10011 十六进制数0 xFE的值是:254 十六进制数0 xFE的二进制表示是11111110 19的
13、二进制表示是:100112.2.浮点类型浮点类型 浮点数据类型有单精度(float)和双精度(double)两种,主要用来存储小数数值,也可以用来存储范围更大的整数。单精度浮点型变量使用关键字float来声明,常量后面必须要有后缀f或F。例如:声明单精度浮点型变量 float height=1.78f;/声明变量height为单精度浮点型,并赋初始值为1.78 float weight=56.8F;/声明变量weight为单精度浮点型,并赋初始值为56.8 float变量在存储float类型数据时保留8位有效数字,例如,如果将常量12345.123456789f赋值给float类型变量x,则x
14、实际输出值为12345.123。对于float类型变量,分配4个字节内存,占32位,float类型变量的取值范围为1.4E-453.4028235E38和-3.4028235E38-1.4E-45。双精度浮点型变量使用关键字double来声明,常量后面可以有后缀d或D,也可以省略,浮点类型默认为double型。例如:声明双精度浮点型变量 double a=1.24d;double b=4.87D;double c=3.14;2.3.1基本数据类型 double变量在存储double类型数据时保留16位有效数字,分配8个字节内存,占64位,double类型变量的取值范围为4.9E-3241.79
15、76931348623157E308和-1.7976931348623157E308-4.9E-324。2.3.1基本数据类型下述案例示例了浮点类型变量保留的有效位数,代码如下所示。【代码2.2】FloatExample.javapackage com;public class FloatExample public static void main(String args)float x=12345.123456789f;System.out.println(x=+x);double y=12345.12345678912345678d;System.out.println(y=+y);程序
16、运行结果如下:x=12345.123y=12345.1234567891243.3.字符型字符型 Java语言中字符型char是采用16位的Unicode字符集作为编码方式,因此支持世界上各种语言的字符。char通常用于表示单个字符,字符值必须使用单引号()括起来。例如:char=A;/声明变量c为字符型,并赋初值为A字符型char的值有以下三种表示形式:通过单个字符来指定字符型值,例如:A、8、Z等;通过转义字符来表示特殊字符型值,例如:n、t等;直接使用Unicode值来表示字符型值,格式是uXXXX,其中XXXX代表一个十六进制的整数,例如:u00FF、u0056等。2.3.1基本数据类
17、型例如:使用转义字符赋值char a=;/变量a表示一个单引号 char b=;/变量b表示一个反斜杠4.4.布尔类型布尔类型 布尔类型又称逻辑类型,使用关键字boolean来声明,只有true和false两种值。布尔类型的默认值是false,即如果定义一个布尔变量但没有赋初始值,默认的布尔变量值是false。布尔类型通常用于逻辑判断,尤其多用在程序的流程控制中。例如:声明一个boolean类型变量 boolean male=true;/声明变量male为布尔类型,并赋初始值为true2.3.1基本数据类型2.3.1基本数据类型程序运行结果如下:isA=falseisB=trueisB is
18、true下述案例示例了布尔数据类型的应用,代码如下所示。【代码2.3】BooleanExample.javapackage com;public class BooleanExample static boolean isA;/定义一个布尔值,使用默认值 static boolean isB=true;/定义一个布尔值,赋初始值为true public static void main(String args)System.out.println(isA=+isA);/输出不布尔值isA的结果System.out.println(isB=+isB);/输出不布尔值isB的结果/输出isA为tr
19、ue则输出isA is trueif(isA=true)System.out.println(isA is true);/输出isB为true则输出isB is trueif(isB)System.out.println(isB is true);2.3.2引用数据类型 引用类型变量中的值是指向内存“堆”中的指针,即该变量所表示数据的地址。Java语 言中通常有5种引用类型:数组:具有相同数据类型的变量的集合。类(class):变量和方法的集合。接口(interface):一系列方法的声明,方法特征的集合。枚举(enum):一种独特的值类型,用于声明一组命名的常数。空类型(null type)
20、:空引用,即值为null的类型。空类型没有名称,不能声明一个null类型的变量,null是空类型的唯一值。空引用只能被转换成引用类型,不能转换成基本类型,因此不要把一个null值赋给基本数据类型的变量。引用数据类型2.3.3数据类型转换 在Java程序中,不同的基本类型的值经常需要进行相互转换。Java语言提供7个基本数据类型间的相互转换,转换的方式有两种:自动类型转换和强制类型转换。1.1.自动类型转换自动类型转换 自动类型转换是将某种基本类型变量的值直接赋值给另一种基本类型变量。当把一个数值范围小的变量直接赋值给一个数值范围大的变量时,系统将进行自动类型转换,否则就需要强制类型转换。Jav
21、a语言中7个基本数据类型间的自动类型转换如图2.1所示。在图2.1中,顺着箭头方向可以进行自动类型转换。其中,实线箭头表示无精度损失的转换,而虚线箭头则表示在转换过程中可能丢失精度,即会保留正确的量级,但精度上会有一些损失(小数点后所保留的位数)。数据类型转换2.3.3数据类型转换2.2.强制类型转换强制类型转换 当把一个数值范围大的变量赋值给一个数值范围小的变量时,即沿图2.1中箭头反方向赋值时,则必须使用强制类型转换。强制类型转换的基本格式如下:数据类型 变量1=(数据类型)变量2;例如:int a=56;char c=(char)a;/把整型变量a强制类型转换为字符型2.3.3数据类型转
22、换下述案例示例了自动类型转换与强制类型转换的应用,代码如下所示。【代码2.4】TypeChangeExample.javapackage com;public class TypeChangeExample public static void main(String args)byte b=8;char c=B;int a=12;long l=789L;float f=3.14f;double d=5.3d;int i1=a+c;/字符型变量c自动转换为整型,参加加法运算System.out.println(i1=+i1);long l1=l-i1;/整型变量i1自动转换为长整型,参加减法运
23、算System.out.println(l1=+l1);float f1=b*f;/字节型变量b自动转换为浮点型,参加乘法运算System.out.println(f1=+f1);double d1=d/a;/整型变量a自动转换为双精度,参加除法运算System.out.println(d1=+d1);int i2=(int)f1;/将浮点型变量f1强制类型转换 为整数 System.out.println(i2=+i2);/整型变量a自动类型转换为长 整型后参加除法运算,/算出的长整型结果再强制类 型转换为字符型 char c2=(char)(l/a);System.out.println(
24、c2=+c2);该程序运行结果如下所示:i1=78l1=711f1=25.12d1=0.44166666666666665i2=25c2=A第第4 4节节part运算符 运算符也称为操作符,是一种特殊的符号,用来将一个或多个操作数连接成执行性语句,以实现特定功能。Java中的运算符按照操作数的个数可以分为三大类型:一元运算符:只操作一个操作数;二元运算符:操作两个操作数;三元运算符:操作三个操作数。运算符本节概述Java中的运算符按操作数分类和功能分类如表2-6所示。2.4.1自增、自减运算符 +是自增运算符,将操作数在原来的基础上加1,-是自减运算符,将操作数在原来的基础上减1。使用自增、自
25、减运算符时需要注意以下两点:自增、自减运算符只能操作单个数值型的变量(整型、浮点型都行),不能操作常量或表达式;自增、自减运算符可以放在操作数的前面(前缀自增自减),也可以放在操作数后面(后缀自增自减)。前缀自增自减的特点是先把操作数自增或自减1后,再放入表达式中运算,后缀自增自减的特点是先使用原来的值,当表达式运算结束后再将操作数自增或自减1。自增、自减运算符2.4.1自增、自减运算符下述案例示例了自增自减运算符的应用,代码如下所示。【代码2.5】SelfIncreaseExample.javapackage com;public class SelfIncreaseExample publ
26、ic static void main(String args)int a=5;int b=+a+8;/a先自增变为6,再与8相加,最后b的值是14System.out.println(b的值是:+b);int c=a+;System.out.println(c的值是:+c);System.out.println(a的值是:+a);int d=10;System.out.println(前缀自减-d的值是:+-d);System.out.println(当前d的值是:+d);System.out.println(后缀自减d-的值是:+d-);System.out.println(当前d的值是:
27、+d);程序运行结果如下:b的值是:14c的值是:6a的值是:7前缀自减-d的值是:9当前d的值是:9后缀自减d-的值是:9当前d的值是:82.4.2算 术 运 算 符 算术运算符用于执行基本的数学运算,包括加(+)、减(-)、乘(*)、除(/)以及取余(%)运算符,如表2-7所示。算术运算符 需要注意的是:需要注意的是:如果/和%运算符的两个操作数都是整数类型,则除数不能是0,否则引发除数为0异常。但如果两个操作数有一个是浮点数,或者两个都是浮点数,此时允许除数是0或0.0,任何数除0得到的结果是正无穷大(Infinity)或负无穷大(-Infinity),任何数对0取余得到的结果是非数:N
28、aN。2.4.2算 术 运 算 符package com;public class MathOperExample public static void main(String args)int a=5;int b=3;System.out.println(a=+a+,b=+b);System.out.println(a+b=+(a+b);/字符串连接System.out.println(a连接b=+a+b);System.out.println(a-b=+(a-b);/两个数相减,结果为2System.out.println(a*b=+(a*b);/两个数相乘,结果为15System.out
29、.println(a/b=+(a/b);/两个整数相除,结果为1System.out.println(a%b=+(a%b);/两个整数取余,结果为2System.out.println(5.1/3=+(5.1/3);/两个浮点数相除,结果为1.7System.out.println(5.2%3.1=+(5.2%3.1);/两个浮点数取余,结果为2.1System.out.println(3.1/0=+(3.1/0);/正浮点数除以0,结果为InfinitySystem.out.println(-8.8/0=+(-8.8/0);/负浮点数除以0,结果为-InfinitySystem.out.pr
30、intln(5.1%0=+(5.1%0);/正浮点数对0取余,结果为NaNSystem.out.println(6.6%0=+(6.6%0);/负浮点数对0取余,结果为NaNSystem.out.println(3/0=+(3/0);/整数除以0,将引发异常 下述案例示例了算术运算符的应用,代码如下所示。【代码2.6】MathOperExample.java程序运行结果如下:a=5,b=3a+b=8a连接b=53a-b=2a*b=15a/b=1a%b=25.1/3=1.75.2%3.1=2.13.1/0=Infinity-8.8/0=-Infinity5.1%0=NaN6.6%0=NaNExc
31、eption in thread main java.lang.ArithmeticException:/by zero at com.MathOperExample.main(MathOperExample.java:20)2.4.3关系运算符 关系运算符用于判断两个操作数的大小,其运算结果是一个布尔类型值(true或false)。Java语言中的关系运算符如表2-8所示。关系运算符 需要注意的是:需要注意的是:关系运算符中=比较特别,如果进行比较的两个操作数都是数值类型,即使它们的数据类型不同,只要它们的值相等,都将返回true。例如a=97返回true,5=5.0也返回true。如果两个
32、操作数都是引用类型,则只有当两个引用变量的类型具有继承关系时才可以比较,且这两个引用必须指向同一个对象(地址相同)才会返回true。如果两个操作数是布尔类型的值也可以进行比较。例如true=false返回false。2.4.3关系运算符下述案例示例了关系运算符的应用,代码如下所示。【代码2.7】CompareOperaExample.javapackage com;public class CompareOperaExample public static void main(String args)int a=5;int b=3;System.out.println(a+b+结果为+(a b
33、);System.out.println(a+=+b+结果为+(a=b);System.out.println(a+b+结果为+(a b);System.out.println(a+=+b+结果为+(a 3结果为true5=3结果为true53结果为false5)、左移位()。位运算符Java语言中的位运算符功能描述如表2-11所示。2.4.5位运算符按位运算符所遵循的真值表如表2-12所示。2.4.5位运算符下述案例示例了位运算符的应用,代码如下所示。【代码2.9】ByteOperaExample.javapackage com;public class ByteOperaExample p
34、ublic static void main(String args)int a=0b0101010;int b=0b0001111;System.out.println(a=+Integer.toBinaryString(a);System.out.println(b=+Integer.toBinaryString(b);System.out.println(a=+Integer.toBinaryString(a);/按位非System.out.println(a&b=+Integer.toBinaryString(a&b);/按位与System.out.println(a|b=+Integ
35、er.toBinaryString(a|b);/按位或System.out.println(ab=+Integer.toBinaryString(ab);/按位异或System.out.println(a1=+Integer.toBinaryString(a1=+Integer.toBinaryString(a1);/右移System.out.println(a1=+Integer.toBinaryString(a1);/无符号右移 程序运行结果如下:a=101010b=1111a=11111111111111111111111111010101a&b=1010a|b=101111ab=100
36、101a1=10101a1=101012.4.6赋值运算符 赋值运算符用于为变量指定变量值,Java中使用“=”作为赋值运算符。通常使用“=”可以直接将一个值赋给变量。例如:int a=3;float b=3.14f;除此以外,也可以使用“=”将一个变量值或表达式的值赋给另一个变量。例如:int a=3;float b=a;double d=b+3;赋值运算符 赋值运算符可与算术运算符、位运算符结合,扩展成复合赋值运算符。扩展后的复合赋值运算符如表2-13所示。2.4.6赋值运算符下述案例示例了赋值运算符的使用,代码如下所示。【代码2.10】ValueOperExample.javapacka
37、ge com;public class ValueOperExample public static void main(String args)int a=8;int b=3;System.out.println(a=+a+,b=+b);System.out.println(a+=b,a=+(a+=b);System.out.println(a-=b,a=+(a-=b);System.out.println(a*=b,a=+(a*=b);System.out.println(a/=b,a=+(a/=b);System.out.println(a%=b,a=+(a%=b);System.out
38、.println(a&=b,a=+(a&=b);System.out.println(a|=b,a=+(a|=b);System.out.println(a=b,a=+(a=b,a=+(a=b);System.out.println(a=b,a=+(a=b);程序运行结果如下所示:a=8,b=3a+=b,a=11a-=b,a=8a*=b,a=24a/=b,a=8a%=b,a=2a&=b,a=2a|=b,a=3a=b,a=3a=b,a=02.4.7条件运算符Java语言中只有一个条件运算符是“?:”,也是唯一的一个三元运算符,其语法格式如下:表达式?value1:value2其中:表达式的值必须
39、为布尔类型,可以是关系表达式或逻辑表达式;若表达式的值为true,则返回value1的值;若表达式的值为false,则返回value2的值。例如:/判断ab是否为真,如果为真则返回a的值,否则返回b的值,/实现获取两个数中的最大数 ab?a:b条件运算符2.4.7条件运算符下述案例示例了条件运算符的使用,代码如下所示。【代码2.11】ConditionOperExample.javapackage com;public class ConditionOperExample public static void main(String args)int a=56;int b=45;int c=7
40、8;System.out.println(a b?a:b=+(a b?a:b);System.out.println(a c?a:c=+(a c?a:c);程序运行结果如下所示:a b?a:b=56a c?a:c=782.4.8运算符优先级 通常数学运算都是从左到右,只有一元运算符、赋值运算符和三元运算符除外。一元运算符、赋值运算符和三元运算符是从右向左结合的,即从右向左运算。乘法和加法是两个可结合的运算,即+、*运算符左右两边的操作数可以互换位置而不会影响结果。运算符具有不同的优先级,所谓优先级是指在表达式运算中的运算顺序。在表达式求值时,会先按运算符的优先级别由高到低的次序执行,例如,算术运算符中采用“先乘除后加减,先括号内后括号外”。表2-14列出了包括分隔符在内的所有运算符的优先级,上一行的运算符总是优先于下一行的。运算符优先级2.4.8运算符优先级 需要注意的是:需要注意的是:不要把一个表达式写得太复杂,如果一个表达式过于复杂,则可以把它分成多步来完成;不要过多依赖运算符的优先级来控制表达式的执行顺序,以免降低可读性,尽量使用()来控制表达式的执行顺序。本章课后作业见教材