第2章 Java语言基础
2.1 标识符、保留字和分隔符 2.1.1 标识符 程序中使用的各种数据对象如符号常量、变量、方法、类等都需要一定的名称,这种名称叫做标识符(identifier)。 Java的标识符由字母、数字、下划线(_)或美元符($)组成,但必须以字母、下划线和美元符开始。 Java标识符是大小写敏感的,没有字符数的限制。
2.1.2 保留字 保留字(reserved word)又称为关键字,是Java语言本身使用的标识符,它有其特定的语法含义。所有的Java保留字将不能被用作标识符。 2.1.3 分隔符 分隔符用来分隔开Java程序中的基本语法元素,可分为注释(单行和多行注释)、空白符(空格、回车和制表符)和普通分隔符(大括号、分号、逗号和冒号)三种。
2.2 数据类型 2.2.1 数据类型概述 计算机程序处理的对象即各种数据,数据类型是指数据的内在表现形式。 根据现实世界数据的不同形式,数据就划分为多种不同的类型。数据类型不同,能进行的运算不同,取值范围也不同,计算机语言中还反映为数据的存储长度和形式不同。
Java语言的数据类型 基本类型 数值类型 整型(byte、short、int、long) 实型(float、double) 字符型(char) 布尔型(boolean) 复合类型 数组 类(class) 接口(interface)
程序中所处理的数据表现为两种形式:常量和变量。 1.常量 Java中的常量值是用文字串表示的,反映了一类在程序执行中不能变化的量。 2.2.2 常量与变量 程序中所处理的数据表现为两种形式:常量和变量。 1.常量 Java中的常量值是用文字串表示的,反映了一类在程序执行中不能变化的量。 常量区分为不同的类型,如: 整型常量123 实型常量4.56 字符常量'a‘ 布尔常量true和false 字符串常量"Java programming "
2. 变量 为了在Java中存储一个数据,必须将它容纳在一个变量之中。在变量中可根据需要存入不同的数据,这就是“变量”的含义。变量具有名称、类型、值和作用域等特性。在使用一个变量前必须先定义。变量定义是用标识符为变量命名、确定其数据类型,还可以根据需要为它赋初值(变量初始化)。定义了变量即为变量指定了存储方式。若是基本类型的变量,因为它们的存储长度是固定的,如何分配存储单元就确定了。若是复合类型的变量,定义后还需要用new运算符为用户数据分配存储单元,复合类型变量中存储用户数据存储单元的引用(指针)。
可以用如下语法定义变量: 类型 标识符[[ = 初始赋值] ,标识符]; 该语句告诉编译器用指定的类型和以标识符为名字建立一个变量,这里的分号将告诉编译器这是一个说明语句的结束;方格中的逗号和标识符表示可以把几个类型相同的变量放在同一语句进行说明,变量名中间用逗号分隔。 在创建了一个变量以后,就可以给它赋值,或者用运算符对它进行允许的运算。
2.3 基本类型 2.3.1整型数据 整型数据是最普通的数据类型,可表示日常生活中的整数。 1.整型常量 Java的整型常数有三种形式:十进制、十六进制和八进制。 十进制整数以10为基数,用0~9这10个数字和正、负号组成,如123,-456,0等。在Java中,十进制整数的第一位数字不能为0。
十六进制整数以16为基数,用0~9的10个数字、字母A~F(小写也可,代表10~15这些整数)和正、负号组成。十六进制整数必须以0X或0x作为开头。如0x123,-0xabc等。 八进制整数以8为基数,用0~7的8个数字和正、负号组成。八进制整数必须用0开始,如0567,-0123等。 每一个整型常数默认为int类型,占有32位(即4个字节)的存储空间。整型常数所表示的范围为2,147,483,647~2,147,483,648,若要使用更大的数,可用64位(8字节)的长整型数(long类型)。若希望把一个整数强制存为一个长整型数,可以在数字后面加字母l或L。
2.3.2实型(浮点型)数据 1. 实型常量 Java的实型常量有标准和科学计数法两种表现形式。 (1)标准形式,由数字和小数点组成,且必须有小数点,如0.123,4.56,789.0等。 (2)科学计数法形式,数字中带e或E,如123e或4.56E3,其中e或E前必须有数字,且e或E后面的数字(表示以10为底的乘幂部分)必须为整数。 实数后面可带后缀F,f或D,d,分别表示单精度实数和双精度实数。
2.3.3 字符型数据 字符型char数据是由一对单引号括起来的单个字符。Java使用Unicode格式的16位字符集,而不仅仅为ASCII字符集,因此char类型的范围从0到65535。Unicode能够容纳所有语言字符集,包括拉丁语、希腊语、阿拉伯语、希伯来语、汉语、日语、韩语等各国语言,因此使用16位是非常必要的。 在Java语言中,以反斜杠(\)开头的多个字符表示一个转义字符,转义字符一般用于表示某些非图形(非可视)字符。
布尔型是一个独立的类型,它不像C语言中的布尔型代表0和1两个整数,由于这个原因,Java中的布尔类型不能转换成数字。 2.3.4 布尔型数据 布尔boolean类型是最简单的一种数据类型,布尔数据只有两个值:true和false,且都是保留字,表示“真”和“假”这两种状态。关系运算和逻辑运算返回布尔类型的值。 布尔型变量用boolean定义,例如: boolean mouseOn = true; boolean done = false; 布尔型是一个独立的类型,它不像C语言中的布尔型代表0和1两个整数,由于这个原因,Java中的布尔类型不能转换成数字。
字符串常量是用双引号括起来的零个或多个字符(包括转义字符)。例如: 2.3.5 字符串数据 1.字符串常量 字符串常量是用双引号括起来的零个或多个字符(包括转义字符)。例如: " " \\ 空串 "我们赢了!\n" \\ 包含转义字符的字符串 一个长字符串可以用“+”号分成几个短字符串。例如: "中国 北京 "+ "2008 奥运!" \\ 一个字符串 在Java语言中,每个字符串常量被作为字符串类String的对象来处理。
2.字符串变量 在Java语言中,字符串变量是对象,是复合类型。有两种字符串变量类型:String类和StringBuffer类。String类是常量类,初始化后不能改变;StringBuffer类是字符串缓冲区,可以修改。例如: String str1 = new String("This is a string."); String str2 = "This is a string."; StringBuffer str3 = new StringBuffer(); StringBuffer str4 = new StringBuffer("This is a string.");
2.3.6 缺省初始值 在Java程序中,每个变量都对应一个值,不存在没有值的变量。若一个变量只声明而没有初始化,则使用它的缺省初值。对于数值数据,缺省数值为相应类型的零;字符的缺省初值为'\u0000';布尔初值为false;Object类型初值为null。
2.4 运算符 运算符的作用是与一定的运算数据组成表达式来完成相应的运算。对不同的数据类型,有着不同的运算符。对运算符,有运算对象(操作数)个数及类型、运算优先级、结合性等特性。 Java语言对运算符的优先级、结合性和求值顺序有明确的规定,从根本上消除了运算符运算过程的二义性以及结果不统一的弊端。
2.4.1 算术运算符 算术运算符按操作数的多少可分为一元(或称单目)和二元(或称双目)两类,一元运算符一次对一个操作数进行操作,二元运算符一次对两个操作数进行操作。算术运算符的操作数类型是数值类型。 一元运算符有+、-、++和--。一元运算符的结合性是右结合性。 二元运算符有+、-、*、/和%,这些运算符并不改变操作数的值,而是返回一个必须赋给变量的值,二元算术运算符具有左结合性。
2.4.2关系运算符 关系运算符用于确定一个数据与另一个数据之间的关系,即进行关系运算。所谓关系运算是比较运算,将两个值进行比较。关系运算的结果值为true、false(布尔型)。Java语言提供了6种关系运算符,它们是>(大于)、<(小于)、>=(大于或等于)、<=(小于或等于)、!=(不等于)和==(等于) ,都是双目运算符。 运算符“==”和“!=”的运算优先级低于另外四个关系运算符。
2.4.3布尔运算符 布尔运算符可以对布尔类型的数据(布尔常量、布尔变量、关系表达式和布尔表达式等)进行运算,结果也为布尔类型。Java语言的布尔运算符见下表: 运算符 名称 例子 ! 逻辑非 !a && 简洁与 a && b || 简洁或 a || b ^ 异或 a ^ b & 非简洁与 a & b | 非简洁或 a | b
布尔运算符的运算规则如下: (1)单目运算符!:将布尔值取反。 (2)双目运算符&&和&:当两个运算对象的值都为true时,结果为true,其他情况均为false。 (3)双目运算符||和|:当两个运算对象的值都为false时,结果为false,其他情况均为true。 (4)双目运算符^:当两个运算对象的值不同时为true,相同时为false。 注意:简洁与、或和非简洁与、或的结果有时不同。非简洁与、非简洁或运算时,运算符两边的表达式都先要运算执行,然后两表达式的结果再进行与、或运算。简洁与、简洁或运算时,若只运算左边表达式即可确定与、或结果时,则右边的表达式将不会被计算。
2.4.4 位运算符 位运算符用来对二进制位进行运算,运算操作数应是整数类型,结果也是整数类型。Java中提供了7种位运算符,它们是~ (按位取反)、& (与运算)、| (或运算)、^ (异或运算)、<< (左移)、>> (算术右移)和>>> (逻辑右移)。其中前四种称为位逻辑运算符,后三种称为算术移位运算符。
2.4.5 赋值运算符 赋值运算符都是二元运算符,具有右结合性。 1.简单赋值运算符(=) 赋值运算符“=”用来将一个数据赋给一个变量。在赋值运算符两侧的类型不一致的情况下,若左侧变量的数据类型的级别高,则右侧的数据被转换为与左侧相同的高级数据类型,然后赋给左侧变量。否则,需要使用强制类型转换运算符。 2.复合赋值运算符 Java语言允许使用复合赋值运算符,即在赋值符前加上其他运算符。复合赋值运算符是表达式的一种缩写。例如:a += 5基本等价于a = a + 5。复合赋值运算符有11种。
条件运算符是一种三元运算符,它的格式如下: 2.4.6 条件运算符 条件运算符是一种三元运算符,它的格式如下: 布尔表达式 ?表达式1: 表达式2 在这个式子中,先计算布尔表达式的真假,若为真,则计算并返回表达式1,若为假,则计算并返回表达式2。例如: (a > b) ? a : b; // 将返回a和b中较大的那个数值。
2.4.7 字符串运算符 运算符“+”可以实现两个或多个字符串的连接,也可实现字符串与其他类对象的连接,在连接时,其他类对象会被转换成字符串。另外,运算符“+=”把两个字符串连接的结果放进第一个字符串里。例如,当想把几项输出内容输出在同一行里时使用的就是“+”运算符。
2.5 常用Java数值计算方法 在Java的类Math中包含了一些数值常量,如E和PI,以及一些基本的数值计算方法,如指数、对数、平方根和三角函数等,为用户程序进行数值计算带来了方便。常用的数值方法有:abs ()绝对值、sin()正弦值、cos()余弦值、tan()正切值、asin()反正弦值、acos()反余弦值、atan()反正切值、ceil()求不小于参数的最小整数、floor()求不大于参数的最大整数、pow(a,b)求a的b次方、random()产生0.0~1.0的伪随机数、sqrt()平方根、log()自然对数、max(a,b)求a,b中的大者、min(a,b)求a,b中的小者等。
【例2.5】类Math中常量和方法的使用。 class UseMath { public static void main(String args[]) { double a = 3.0, b = 4.0; double c = Math.sqrt(a * a + b * b); System.out.println("半径为 3.0 的圆面积是 : " + Math.PI * a * a); System.out.println("直角三角形直角边为 3.0 和 4.0 时 的斜边长为 : " + c); System.out.println(" -8 和 -4 的较大者是 : " + Math.max(-8, -4)); System.out.println("–18的绝对值是 : " + Math.abs(-18)); System.out.println("不小于45.7的最小整数是 : " + Math.ceil(45.7));
程序运行结果如下: System.out.println("不大于45.7的最大整数是 :" + Math.floor(45.7)); System.out.println(“sin25度的值是 :” + Math.sin(25.0/180*Math.PI)); } 程序运行结果如下: 半径为 3.0 的圆面积是 :28.274333882308138 直角三角形直角边为 3.0 和 4.0 时的斜边长为 : 5.0 -8 和 -4 的较大者是 :-4 -18的绝对值是 :18 不小于45.7的最小整数是 :46.0 不大于45.7的最大整数是 :45.0 sin25度的值是 :0.42261826174069944
import static java.lang.Math.*; 注意:程序中使用了一些Math类中的常量和方法,它们都是Math类的静态成员,一般情况下,可通过“类名.静态成员名”的格式来引用一个类中的静态成员。但若使用了Java语言的静态引入功能,则可省去静态成员名称前的类名。即若在程序的最前面增加语句: import static java.lang.Math.*; 那么,程序中所有的Math可省去不写,这样可简化程序的书写和输入。
2.6 表达式 表达式是由操作数和运算符按一定的语法形式组成的符号序列。每个表达式结果运算后都会产生一个确定的值,称为表达式的值。表达式的值是有类型的,该类型称为表达式类型。表达式类型由运算符和参与运算的数据的类型决定。可以是简单类型,也可以是复合类型。 可以按表达式值的类型将表达式分类。
在一个表达式中可能有不同类型的数据进行混合运算,这是允许的,但在运算时,Java将不同类型的数据转换成相同类型,再进行运算。 2.6.1 类型转换 在一个表达式中可能有不同类型的数据进行混合运算,这是允许的,但在运算时,Java将不同类型的数据转换成相同类型,再进行运算。 1. 自动类型转换 整型、实型和字符型数据可以进行混合运算。在运算中,不同类型的数据先转换成相同类型,然后再进行运算。转换从低级到高级。可混合运算数据类型从低到高排列如下: 低-> byte,short,char,int,long,float,double -> 高
高级数据要转换为低级数据时,需进行强制类型转换,Java不象C/C++那样允许自动类型转换。从一种类型转换到另一种类型可以使用下面的语句: 2. 强制类型转换 高级数据要转换为低级数据时,需进行强制类型转换,Java不象C/C++那样允许自动类型转换。从一种类型转换到另一种类型可以使用下面的语句: int a; char b; b=(char)a; 加括号的char告诉编译器想把整型变成字符并把它放在b里。
在表达式的求值过程中,运算中间值的精度有时会超出操作数的取值范围。例如: 3. 表达式求值中的自动类型提升 在表达式的求值过程中,运算中间值的精度有时会超出操作数的取值范围。例如: byte x = 30,y = 50,z = 100; int a = x * y / z; 在运算x*y项时,结果1500已经超出了操作数byte类型的范围。为解决这类问题,Java语言在对表达式求值时,自动提升byte或short类型的数据为int类型的。
自动类型提升对数据的运算带来了方便,但也容易引起编译错误。例如: byte x = 30; x = - x; // 编译错误!不能向byte变量赋int值
2.6.2 优先级 在一个表达式中可能有各种运算符,Java语言规定了表达式中出现各种运算符的时候,哪种运算符先进行运算,哪种运算符后进行运算的运算符运算顺序,称为运算符的优先级,它指明了同一表达式中多个运算符被执行的次序,同一级里的操作符具有相同的优先级。在表达式中,优先级高的运算符先进行运算。
2.6.3 结合性 在表达式中出现多个相同优先级的运算符时,就需要考虑结合性。结合性确定同级运算符的运算顺序。运算符有左结合性和右结合性两种。左结合性指的是从左向右使用运算符。例如二元算术运算符具有左结合性,计算a + b - c时,操作数b的左、右运算符 +、- 是同级运算符,计算时,b先与左边的 + 结合,计算a + b,其和再与c相减;而右结合性是从右向左使用运算符。例如,赋值运算符具有右结合性,计算a = b = c时,操作数b的左、右运算符都是同级的赋值运算符,所以,先执行b = c,再执行a = b。
2.7 包装类(wrapper class) Java语言中专门提供了所谓的包装类(wrapper class)。这些类将基本类型包装成类。与基本类型对应的包装类有Byte 、Short 、Integer 、Long 、Character 、Float 、Double 、Boolean 和Void 。
使用包装类的方法与其他类一样,定义对象的引用、用new运算符创建对象,用方法来对对象进行操作。 例如: Integer i = new Integer(10); // i 是 Integer类的一个对象,值为10 Integer j = new Integer(20); // j 是 Integer类的一个对象,值为20 【例2.8】包装类Integer类常用方法的使用以及与int数据进行混合运算的例子。
class UseWrapper { public static void main(String args[]) { int num = 2005; System.out.println(num + " 的二进制是: " + Integer.toBinaryString(num)); // 转换十进制数为二进制数 System.out.println(num + " 的八进制是: " + Integer.toOctalString(num)); // 转换十进制数为八进制数 System.out.println(num + " 的十六进制是: " + Integer.toHexString(num)); // 转换十进制数为十六进制数 Integer iobj = Integer.valueOf("123"); Integer iobj1 = new Integer(234); Integer iobj2 = new Integer("234"); int i = iobj.intValue(); System.out.println("iobj = " + iobj); System.out.println("i = " + i);
程序运行结果如下: System.out.println("iobj1==iobj2 ? " + iobj1.equals(iobj2)); // 比较两个对象是否相等 iobj = iobj + num; // int数据和Integer数据可以混合运算 System.out.println("iobj = " + iobj); num = iobj + num; System.out.println("num = " + num); } 程序运行结果如下: 2005 的二进制是: 11111010101 2005 的八进制是: 3725 2005 的十六进制是: 7d5 iobj = 123 i = 123 iobj1==iobj2 ? true iobj = 2128 num = 4133
2.8 输入输出初步 2.8.1标准输入输出 1.标准输出 (1)print和println方法 可以用System.out.println在程序中可以将常量、变量或表达式的值输出到屏幕。println方法可有0个或1个参数。若参数是0个,则输出一回车换行,光标移动到下一行行首;若有一个参数,该参数可以是char,byte,int,boolean,float,double,String,char[](字符数组)和Object(对象)类型的,各种类型的数据转换成相应的字符串类型输出。输出给定所有内容后,输出一个回车换行。
(2)printf和format格式输出方法 另外也常用System.out.print进行输出,print方法需要一个参数来输出,可用的参数类型与println相同,输出参数的值后不输出回车换行,因此,若输出内容本身不包含控制光标的内容或未满行,System.out.print输出后,光标将停留在输出内容后。 (2)printf和format格式输出方法 要控制输出数据的格式,可使用System.out.printf和类似的System.out.format方法,在方法的参数中对每一输出项(表达式),都可在一个格式控制字符串中用%开始的格式符进行格式控制。 例如: System.out.printf("a=%d\tb=%f\tc=%c",a,b,c); 或:System.out.format("a=%d\tb=%f\tc=%c",a,b,c);
格式控制字符串中的其他字符,无格式控制功能,输出时将按字符原样输出。如上例中的"a="、"b="、"c="和"\t"(制表符)将按原意输出。 其中的输出项为a、b和c三项,在格式控制字符串"a=%d\tb=%f\tc=%c"中有三个格式符对它们进行控制,未指出顺序时,按照自然顺序进行格式控制,即:%d控制a 使其以十进制整数形式输出;%f控制b使其以十进制实数形式输出;%c控制c使其以字符形式输出。为了能得到正确输出的数据和格式,不同类型的输出项应使用不同的格式符来进行格式控制输出。适用于基本类型和字符串类型输出的常用格式符有: %b 布尔型数据 %c 字符 %d 十进制整数 %f 十进制实数 %e或%g 科学记数法形式的十进制实数 %s 字符串 格式控制字符串中的其他字符,无格式控制功能,输出时将按字符原样输出。如上例中的"a="、"b="、"c="和"\t"(制表符)将按原意输出。
2.标准输入 (1)read方法 可以用System.in.read()从键盘输入整数值在0~255之间的byte值(int类型)。若程序运行时需要从键盘输入其他类型的数据,则需要使用Java提供的输入/输出功能。不论需从键盘输入何种类型的数据,Java从键盘接收数据都是以字符串的形式进行,再根据实际数据的需要进行类型转换。 应用本方法时要使用Java的异常处理机制。
【例2.9】从键盘输入一个字符,并输出它在Unicode字符集中的前一字符和后一字符。 import java.io.*; // 引入java.io包 class CharDemo { public static void main(String args[]) throws IOException{ char c,c1,c2; c=(char)System.in.read(); // 输入字符 c1=(char)(c-1); c2=(char)(c+1); System.out.println(" : " + c1); System.out.println(" : " + c2); }
(2)使用next方法 若使用Java提供java.util.scanner类中的各种next方法,可从键盘输入各种基本类型和字符串类型的数据。不论需从键盘输入何种类型的数据,Java从键盘接收数据都是以字符串的形式进行,next方法要根据输入数据的类型来选用。有nextByte、nextInt、nextShort、nextLong、nextFloat、nextDouble、nextBoolean和next(以空格和回车为结束标记的字符串输入)等适用于不同类型数据输入的方法。使用next方法进行键盘输入的例子如下。
【例2.10】从键盘输入三角形的三个边长,求这个三角形的面积。 import java.util.Scanner; class TriArea{ public static void main(String args[]){ System.out.printf("请输入三角形的三边长:\n"); Scanner sc = new Scanner(System.in); double a = sc.nextDouble(); double b = sc.nextDouble(); double c = sc.nextDouble(); double t = (a+b+c)/2.0; double s = Math.sqrt(t*(t-a)*(t-b)*(t-c)); System.out.format("三角形的面积为%f\n",s); }
1.使用showMessageDialog(输出信息对话框)方法 2.8.2对话框输入输出 1.使用showMessageDialog(输出信息对话框)方法 Java中的JOptionPane.showMessageDialog方法是用对话框的形式来进行输出,支持一个输出项,在输出内容较多时,也可用字符串连接的形式来输出。例如下面的程序: 【例2.11】求sin30º和cos30º的值。 import javax.swing.JOptionPane; import static java.lang.Math.*; class DialogDemo{ public static void main(String args[]){ String s1="sin30度的值="; s1 = s1 + sin(PI*30/180); s1 = s1 + "\ncos30度的值="; s1 = s1 + cos(PI*30/180); JOptionPane.showMessageDialog(null,s1); }
2.使用inputMessageDialog方法输入信息 例2.11的输出结果如右图所示。 2.使用inputMessageDialog方法输入信息 使用Java提供的javax.swing.JOptionPane类中的showInputDialog方法,可从输入信息对话框中输入一个字符串。需要时,可进行类型转换,得到所需类型的输入数据。 【例2.12】使用对话框进行程序的输入输出。输入一个代表年号的整数,求这一年的元旦是星期几? 元旦是星期几的计算公式(设年号为y,按整数运算): s = y + (y-1) / 4 - (y-1) / 100 + (y-1)/ 400; s除以7的余数即为星期数,余数为0表示星期日。
程序运行的输入输出界面及结果见下图。 import javax.swing.JOptionPane; class YuanDan{ public static void main(String args[]){ int s,y; y=Integer.parseInt(JOptionPane.showInputDialog( "请 输入一个年号:")); s = y + (y-1) / 4 - (y-1) / 100 + (y-1)/ 400; s = s % 7; JOptionPane.showMessageDialog(null,y + " 年的元旦是星期 "+ s); } 程序运行的输入输出界面及结果见下图。
例2.12的输出结果如下图所示。