第2章 Java语言基础
Java语言基础包括Java语言的基本组成、数据类型、运算符、表达式、控制流程等,这些内容是任何一门程序设计语言都必须具备的,因为这是编程的基础。本章主要介绍Java语言的编程基础,为后续的学习打下一个扎实的基础。
2.1 Java语言的基本组成
Java语言主要由以下5 种基本元素组成:标识符、关键字、文字、运算符和分隔符。这5 种元素有着不同的语法含义和组成规则,它们互相配合,共同完成Java语言的语意表达。本节主要学习Java语言这5种元素。
学习目标
通过本节的学习,掌握Java语言的基本组成。
案例内容
案例3 求圆的面积
下面是关于标识符、关键字、分隔符的应用案例,datatype.java代码如下:
public class datatype { public static void main(String args[]) /*public、class、static、void、 main为关键字*/ { final double PI = 3.1416; //定义double常量PI并赋值 int r = 2; //定义r为int型变量并赋值 double s = PI*r*r; //定义s为double型变量并赋值 System.out.println(“输出各变量和常量的值:”); System.out.println(“常量PI = ”+PI); System.out.println(“r = ”+r); System.out.println(“s = ”+s); /*{}、[]、;、()等是分隔符*/ } }
程序运行结果如图2.1所示。
图2.1 程序datatype的运行结果
知识链接
1.标识符
(1)Java语言标识符的定义、命名。Java的标识符由字母、数字、下画线(_)或美元符($)组成,但必须以字母、下画线或美元符开始。Java语言是使用Unicode字符集的。
(2)标识符的命名规则。Java语言标识符的命名规则如表2.1所示。
表2.1 Java语言标识符的命名规则
一般来说,标识符的命名应注意以下几点。
① 大写字母和小写字母被认为是两个不同的字符,因为Java语言对大小写是区分的。例如,My和my被认为是两个不同的标识符。
② 变量名是一个合法的标识符,不能以数字开头,而且不能是关键字。
合法的变量名,如myName、value-1、dollar$等;
非法的变量名,如2mail、class(关键字)等。
2.关键字
关键字是Java语言本身使用的标识符,它有其特定的语法含义,如for、while、boolean等都是关键字,并采用小写。所有的关键字都不能用做标识符。下面列举的都是Java语言的关键字:
abstract Boolean break byte case char class if for do double continue default else extents final finally float implements import instanceof int interface long native new null true try void while short return this switch
一般来说,Java语言的关键字可以根据其用途分为下面几类:
(1)数据声明关键字(boolean, float, int);
(2)循环关键字(continue, while, for);
(3)条件关键字(if, else, switch);
(4)结构关键字(try, throws, catch);
(5)修饰符和访问关键字(private, public, transient);
(6)其他关键字(true, null, super)。
3.注释方式
Java语言中可以采用以下3种注释方式。
(1)“//”:用于单行注释,注释从“//”开始,终止于行尾,主要用于只注释一行。当然,对于多行注释,也可用此方式,即在每行前都加“//”。如:
//一行文字注释
(2)“/*…*/”:用于多行注释,注释从“/*”开始,到“*/”结束,且这种注释不能互相嵌套。它主要用于要插入一段注释,在注释首尾分别加“/*”和“*/”。如:
/*一行或多行文字注释*/
(3)“/**…*/”:是Java语言所特有的doc注释,它以“/**”开始,到“*/”结束。这种注释主要是为支持JDK工具Javadoc而采用的。Javadoc能识别注释中用标记@标识的一些特殊变量,并把doc注释加入它所生成的HTML文件里。这类注释通常用在创建Web页面的HTML文件中,如:
/**多行的文件内容注释*/
4.分隔符
分隔符用来使编译器确认代码在何处分隔,如“,”、“;”等都是Java语言的分隔符。
表2.2列举了一些常用的分隔符。
表2.2 一些常用的分隔符
上机实战
上机实践RelationAndConditionOpEX.java,它是实现算术运算功能的程序,代码如下:
public class RelationAndConditionOpEX { public static void main(String args[ ]) { int a = 5, b = 2; //分别对a和b进行赋值 int c = a/b*8; //定义c为int型变量并赋值 System.out.println(“c = ”+c);//输出c的值 } }
程序运行结果如图2.2所示。
图2.2 程序RelationAndConditionOpEX的运行结果
案例总结
本节主要学习了Java语言中标识符的使用,标识符的定义和命名规则;关键字、注释语句和分隔符的使用。这些都是程序设计中最基本的内容。
习题2.1
1.判断题
(1)int a;这里的a不是标识符。()
(2)if是标识符。()
(3)_hu不可以作为标识符。()
(4)int、true、for、case、new、byte、that都是关键字。()
2.操作题
仿照案例,编写一个简单的程序,求5除以2所得商的整数部分。
2.2 数据类型
Java语言既能以简单的方式存储数据,也能以复杂的方式——类来存储数据,当然还能自定义复杂度更高的数据类型。关于这点,将在后面详细介绍。本节主要学习常量和变量的定义及数据类型的具体应用。
学习目标
通过本节的学习,掌握Java语言中各种数据类型的定义及应用。
案例内容
案例4 定义并输出常量和变量
分析:Java语言中的常量是用文字串表示的,它区分为不同的类型,如整型常量123,实型常量1.123,字符常量“a”,布尔常量true、false,以及字符串常量“this is a constant string.”。
下面是几个常量和变量的定义及输出的案例,datatype.java代码如下:
public class datatype { public static void main(String args[]) { final int F1 = 100; //定义整型常量F1并赋值 int i = 23; //定义i为int型变量并赋值 long l = 300; //定义l为long型变量并赋值 System.out.println(“输出各变量和常量的值:”); System.out.println(“常量F1 = ”+F1); System.out.println(“i = ”+i); System.out.println(“l = ”+l); } }
程序运行结果如图2.3所示。
图2.3 程序datatype的运行结果
知识链接
1.常量与变量
常量是指在程序运行过程中其值不能改变的量。所有的常数都是常量,如1、0.25F、true、‘a’等。此外,还可以在程序中定义一些常量,常量的定义比变量的定义多一个修饰符“final”。另外,常量必须有初始值。
格式:final type identifier=value
在计算圆的面积的时候,需要用到圆周率,此时可以将它定义成一个常量。
final double PI = 3.1416; … area = PI*r*r;
变量是指在程序运行过程中其值可以改变的量。变量是基本存储单位。定义一个变量需要有一个类型、一个标识符,如果需要,还可以加上一个初始值。例如:
type identifier [ = value]
其中的type为类型;identifier为标识符,也就是变量名;value为初始值。
变量的类型可以是基本的数据类型、类名和接口名。变量名可以自己设定,但要像标识符一样遵循一定的规则。
2.整型数据
(1)整型常量。与C、C++相同,Java语言的整型常量有三种形式:
① 十进制整数,如123、−456、0;
② 八进制整数,以0开头,如0123表示十进制数83,−011表示十进制数−9;
③ 十六进制整数,以0X或−0X开头,如0X123 表示十进制数291,−0X12 表示十进制数−18。
对于long型值,则要在数字后加L或1,如123L表示一个长整数。
(2)整型变量。整型变量的类型有byte、short、int、long四种,表2.3列出了这四种类型分别所占内存的位数和其取值范围。
表2.3 整型变量的类型
int类型是最常使用的一种整数类型。而对于大型计算,常会遇到很大的整数,超出int类型所表示的范围,这时要使用long类型。
由于不同的机器对于多字节数据的存储方式不同,有的可能是从低字节向高字节存储,也有的可能是从高字节向低字节存储。因此,在分析网络协议或文件格式时,为了解决不同机器上的字节存储顺序问题,用byte类型来表示数据是非常合适的。但byte类型表示的数据范围很小,容易造成溢出,所以数据范围大时,应避免使用。
short类型则很少使用,因为它限制数据的存储为先高字节、后低字节,这样在某些机器中会出错。
(3)整型变量的声明。例如:
byte b; //声明变量b为byte型 short s; //声明变量s为short型 int i; //声明变量i为int型 long l; //声明变量l为long型
3.浮点型(实型)数据
(1)实型常量。与C、C++相同,Java语言的实型常量有两种表示形式:
① 十进制数形式,由数字和小数点组成,且必须有小数点,如0.123、.123、123.、123.0;
② 科学计数法形式,如123e或123E3,其中e或E之前必须有数字,且e或E后面的数字(表示以10为底的乘幂部分)必须为整数。
实型常量在机器中占64位,具有double型的值。对于float型的常量,只要在数字后加f或F即可,如12.3F,它在机器中占32位,且表示精度较低。
(2)实型变量。实型变量的类型有float和double两种,表2.4列出了这两种类型所占内存的位数和其取值范围。
表2.4 实型变量的类型
双精度类型double比单精度类型float具有更高的精度和更大的表示范围,因此使用更广泛。
(3)实型变量的声明。例如:
float f; //声明变量f为float型 double d; //声明变量d为double型
4.字符型数据
(1)字符型常量。字符型常量是用单引号括起来的一个字符,如‘a’、‘A’。此外,与C、C++相同,Java也提供转义字符,它以反斜杠(\)开头,将其后的字符转变为另外的含义。
下面列出了Java语言中的转义字符:
\’ 单引号字符;
\\ 反斜杠字符;
\r回车;
\n换行;
\f换页;
\t横向跳格;
\b退格;
\ddd 1~3位八进制数据所表示的字符(ddd),八进制的特殊字符序列。在ASCII码八进制值的字符中,ddd为3个八进制数(0~7),如\071是ASCII码为八进制数71(十进制数57)的字符;
\uxxxx 1~4位十六进制数所表示的字符(xxxx),Unicode的换码序列。Unicode十六进制值的字符中,xxxx为4个十六进制数(0~9,A~F),如\u0041是Unicode码为十六进制数41(十进制数65)的字符。
(2)字符型变量。字符型变量的类型是char,它在机器中占16位,其范围为0~65535。字符型变量的声明如下所示:
char c = 'a'; //声明变量c为char型,且赋初值为‘a’
与C、C++不同,Java语言中的字符型数据不能用做整数,因为Java语言不提供无符号整数类型。但可以把字符型数据当做整数数据来操作。例如:
int three = 3; char one = ’1’; char four = (char)(three+one); //four = ’4’
上例中,在计算加法时,字符型变量one被转化为整数,进行相加,最后又把结果转化为字符型。
(3)字符串常量。与C、C++相同,Java语言的字符串常量是用双引号(“ ”)括起来的一串字符,如“This is a string.\n”。但不同的是,Java语言中的字符串常量被作为string类的一个对象来处理,而不是一个数据。
5.布尔型数据
布尔型变量的声明如下:
boolean b = true; //声明b为布尔型变量,且初值为true
与C、C++不同,Java语言中不能通过#define命令把一个标识符定义为常量,而是用关键字final来实现的。如:
final double PI = 3.14159
Java语言中的变量必须遵循“先定义、后使用”的原则,即变量必须先声明,然后才能使用。
Java语言程序中常常需要对一些变量预先设置初值。Java语言规定,可以在定义变量的同时对变量进行初始化。
除了基本的数据类型外,Java语言变量的数据类型也可以是一个内置或用户自定义的类,还可以是一个数组。下面是一些Java语言数据类型的示例:
float x; //float是一个基本数据类型 Float x; //Float是一个内置类 Marquee x; //Marquee是一个用户自定义的类 String[ ] x; //String[ ]是一个String数组
Java语言有8个基本数据类型,它们被嵌入系统而不被看做是对象。同时,Java语言也提供与这些基本数据类型对应的内置类,一般是将第一个字母变成大写作为它们的类名称。这样,这些简单的数据类型也可以有对象形式的数据类型。在声明一个变量时,必须把该变量的数据类型放在变量名的前面。
6.各类型数据间的混合运算
在一个表达式中可能有不同类型的数据进行混合运算,这是允许的,但在运算时,Java语言会先将不同类型的数据转换成相同的类型,然后再进行运算。
例如,系统方法System.in.read返回一个整型数值,但是又需要把它当做一个字符来使用,这时就需要进行类型转换。从一种类型转换到另一种类型可以使用下面的语句:
int a;char b; a = (int)b;
在上面的语句中,加括号的int告诉编译器要把字符b变成整型并把它放在a里。另一方面,如果想做相反的转换,还可以使用下面的语句:
b = (char)a;
整型和字符型变量位长是不同的,整型是32位长,字符型是16位长,所以变量从整型转换到字符型可能会丢失信息。同样,当把64 位的长整型数转换为整型时,由于长整型可能有比32 位更多的信息,因此也很可能会丢失信息。即使两个量具有相同的位数,如整型和浮点型(都是32位),在转换小数时也会丢失信息。Java语言不像C、C++那样允许自动类型转换,所以当进行类型转换时要注意使目标类型能够容纳原类型的所有信息。不会丢失信息的类型转换如表2.5所示。
表2.5 不会丢失信息的数据类型转换列表
上机实战
上机实践test.java,本程序运用了前面介绍的数据类型,代码如下:
public class test { public static void main(String args[ ]) { float a = 3.25F, b = −2.5F; //定义a、b为float型并赋值 int c, d; //定义c、d为int型变量 c = (int) (a*b); //对c进行赋值并强制转变a*b的类型 d = (byte)386; //将386强制转变为byte型并赋值给d System.out.println("c = "+c); System.out.println("d = "+d); } }
程序运行结果如图2.9所示。
图2.9 程序test的运行结果
案例总结
本节介绍了Java语言内部的数据类型——整数型、浮点型、数据型、字符型与布尔型5种。int用来定义整型变量,double用来定义带有小数点的数据类型,其余的long、short、float只有在特定的环境中才用到。此外,每种数据类型都包含以特定格式命名的或未命名的常量。还有,变量在使用之前必须先定义。
习题2.2
1.简答题
(1)下列变量名哪些合法,哪些不合法?
Ab?| @abc 1name _int $85 private ab*5 #abc
(2)Java语言的数据类型有哪几种?
(3)各类型数据间的转换中,不会丢失信息的类型转换有哪些?其原始类型和目标类型分别是什么?
2.操作题
仿照本节案例和上机实战,求一个整数的20%是多少,要求结果为整数(小数部分四舍五入)。
2.3 运算符
任何一种程序语言都有运算符,+、−、*、/ 等都是Java语言的运算符。运算符的作用是,与一定的运算数据组成表达式来完成相应的运算。对于不同的数据类型,有着不同的运算符。本节主要学习运算符的使用。
学习目标
通过本节的学习,掌握各运算符的含义及其具体用法。
案例内容
案例5 用算术运算符作算术运算
分析:算术运算符用于整型或浮点型数据,完成算术运算。
下面是算术运算符的应用案例,ArithmeticDemo.java代码如下:
public class ArithmeticDemo { public static void main(String args[]) { //定义几个数 int i = 37; //a = 9 int j = 42; //b = 18 double x = 27.475; //c = 4 double y = 7.22; //d = 14 System.out.println("变量数值…");//e = −14 System.out.println("i = "+i); System.out.println("j = "+j); System.out.println("x = "+x); System.out.println("y = "+y); //加 System.out.println("加…"); System.out.println("i+j = "+(i+j)); System.out.println("x+y = "+(x+y)); //减 System.out.println("减…"); System.out.println("i−j = "+(i-j)); System.out.println("x−y = "+(x−y)); //乘 System.out.println("乘…"); System.out.println("i*j = "+(i*j)); System.out.println("x*y = "+(x*y)); //除 System.out.println("除…"); System.out.println("i/j = "+(i/j)); System.out.println("x/y = "+(x/y)); //从除法中求得余数 System.out.println("计算余数…"); System.out.println("i%j = "+(i%j)); System.out.println("x%y = "+(x%y)); //混合类型 System.out.println("混合类型…"); System.out.println("i+y = "+(j+y)); System.out.println("i*x = "+(i*x)); } }
程序运行结果如图2.10所示。
图2.10 程序ArithmeticDemo的运行结果
知识链接
1.算术运算符
(1)一元算术运算符。一元算术运算符的用法和描述如表2.6所示。
表2.6 一元算术运算符
注:op表示操作数。
对于“+ +”和“− −”运算符来说,既可以放在操作数之前,也可以放在操作数之后,但必须注意两者的区别。
如i+ +与+ +i的区别是:
i+ +在使用i之后,使i的值加1,因此执行完i++后,整个表达式的值为i,而i的值变为i+1。
+ +i在使用i之前使i的值加1,因此执行完++i后,整个表达式和i的值均为i+1。
i− −与− −i同理。
(2)二元算术运算符。二元算术运算符的用法和描述如表2.7所示。
表2.7 二元算术运算符
注:op1、op2分别表示两个操作数(表2.8~表2.11中同)。
Java语言对运算符“+”的作用进行了扩展,使其除了能完成一般意义上的加运算外,还能够进行字符串的连接,例如:
“abc”+“de”,得到串“abcde”。
与C、C++不同,对取模运算符“%”来说,其操作数可以为浮点数,例如:37.2%10=7.2。
二元运算符涉及两个操作数,操作数和运算结果的数据类型有以下关系:如果操作数中有一个为长整型(long),则结果也为长整型;即使两个操作数全是字节型(byte)或短整型(short),结果也均为整型(int);如果操作数为浮点型,只要两个操作数中有一个为双精度,则结果为双精度;只有两个操作数都是单精度浮点数时,结果才是单精度数。运算结果按最大类型存放。
当“/”(除)、“%”(取模)运算中的除数为0时,会产生异常。
2.关系运算符
关系运算符都是二元运算符,如表2.8所示是关系运算符的用法及返回true的情况。
表2.8 关系运算符
在Java语言中,任何数据类型的数据(包括基本类型和组合类型)都可以通过“==”或“!=”来比较是否相等(这与C、C++不同)。
关系运算符“==”可以比较两个相同类型的变量。如果是对象,就只有在两个变量指向同一个对象时,比较的结果才会是真。下面是例子:
m1 = new Mammal( ); m2 = new Mammal( ); boolean b1 = m1 == m2; //b1 = false m1 = m2; boolean b2 = m1 == m2; //b2 = true
第一个比较的结果是false,是因为m1和m2指向不同的对象(尽管它们是同一类型)。第二个比较的结果是true,因为两个变量现在指向同一对象。
大多数时候,可以使用equals()方法来比较对象。这个方法是在Object中定义的,但是必须在Object的子类中实现,才能用来比较对象。
关系运算的返回结果是true或false,而不是像C、C++中的1或0。关系运算符常与布尔逻辑运算符一起使用,作为流程控制语句的判断条件。
3.布尔逻辑运算符
布尔逻辑运算符用于进行布尔逻辑运算,其用法及返回true的情况如表2.9所示。
表2.9 布尔逻辑运算符
说明:
(1)“&&”和“||”是二元运算符,实现逻辑与和逻辑或。
(2)“!”是一元运算符,实现逻辑非。
(3)对于布尔逻辑运算,一般先求出运算符左边表达式的值,如果为true,则整个表达式的结果为true,不必对运算符右边的表达式再进行运算;同样,如果左边表达式的值为false,则不必对右边的表达式求值,整个表达式的结果为false。
4.位运算符
Java语言中提供的位运算符如表2.10所示。
表2.10 位运算符
位运算符中,除“~”以外,其余均为二元运算符。
说明:
(1)按位取反运算符“~”是一元运算符,对数据的每个二进制位取反,即把1 变成0,把0变成1。需要注意的是,“~”运算符与“−”运算符不同,~21≠−21。
(2)位移运算符“<<”、“>>”用于将一个整数的二进制数向左或向右移动。可参考下面的例子(为了简单,使用短整型):
short I = 13; //I=0000000000001101 I = I<<2; //I=0000000000110100 I = I>>3; //I=0000000000000110
该例中,左位移运算符将变量I的每一位向左移动两位,右位移运算符将变量I的每一位向右移动三位。
(3)对于位或运算符“|”,参与运算的两个值,如果两个相应位有一个为1,则该位的运算结果为1。
(4)对于位与运算符“&”,参与运算的两个值,如果两个相应位都为1,则该位的运算结果为1,否则为0,即:
0&0 = 0 0&1 = 0 1&0 = 0 1&1 = 1
5.赋值运算符
赋值运算符左边必须是一个变量,不能是其他内容,例如:a=5,a=b+c*5。
另外,可以在等号前加上某些运算符构成扩展赋值运算符,具体有:+=,−=,*=,/=,%=,&=,|=,^=,<<=,>>=,>>>=。这表示在先进行某种运算之后,再用运算的结果进行赋值。
表2.11列出了所有的赋值运算符及其等价形式。
表2.11 赋值运算符
Java语言可以像C语言一样进行连续赋值,但要注意,除了最右边的是表达式外,左边都是变量,不能是表达式,例如:a=b=c=5。
6.条件运算符
条件运算符(?:)是三元运算符,它的语法是:
expression1? expression2: expression3;
expression1是第一个判断的值,如果为真,计算expression2;否则,计算expression3。
上机实战
上机实践程序ArithmaticOP.java,练习几种运算符的应用,代码如下:
public class ArithmaticOP { public static void main(String args[]) { int a = 5+4; //a = 9 int b = a*2; //b = 18 int c = b/4; //c = 4 int d = b−c; //d = 14 int e = −d; //e = −14 int f = e%4; //f = −2 double g = 18.4; double h = g%4; //h = 2.4 int i = 3; int j = i++; //i = 4,j = 3 int k = ++j; //i = 5,k = 5 System.out.println("a = "+a); System.out.println("b = "+b); System.out.println("c = "+c); System.out.println("d = "+d); System.out.println("e = "+e); System.out.println("f = "+f); System.out.println("g = "+g); System.out.println("h = "+h); System.out.println("i = "+i); System.out.println("j = "+j); System.out.println("k = "+k); } }
程序运行结果如图2.16所示。
图2.16 程序ArithmaticOP的运行结果
案例总结
本案例中详细介绍了6种不同运算符的语法知识和应用实例。运算符的作用是用一定的运算数据组成表达式来完成相应的运算,对不同的数据类型,有着不同的运算符。
习题2.3
1.填空题
(1)i+=100(i=5)的值是_________________。
(2)100%9的值是_________________。
(3)i<<=2(i=2)的值是_________________。
2.操作题
编写一个程序,求exp(4000.0)、10.0/3.0、−10.0/3.0和0.0/0.0的值。