第2章 Java开发基础——Java语言入门
◎ 本章教学微视频:27个 135分钟
学习指引
学习一种编程语言,第一步是要学习它的开发基础,Java语言也不例外。本章就来介绍Java编程语言的开发基础,主要内容包括Java的数据类型、常量与变量、赋值、数据类型、运算符等。
重点导读
- 熟悉Java语言的基础语法。
- 掌握Java语言的数据类型。
- 掌握数据类型转换的方法。
- 掌握Java语言的常量与变量。
- 掌握Java运算符的使用方法。
2.1 剖析第一个Java程序
通过第1章的学习,相信读者已经能够使用Eclipse编写出第一个Java程序“Hello World!”。完整代码如下:
【例2-1】(实例文件:ch02\Chap2.1.txt)使用Eclipse编写第一个Java程序“Hello World!”。
public class Test { public static void main(String[] args) { System.out.println("Hello World!"); } }
运行结果如图2-1所示。
图2-1 “Hello World!”程序的运行结果
下面通过剖析这个程序,让读者对Java程序有更进一步的认识。所有的Java程序都必须放在一个类之中才可以执行,定义类的语法形式如下:
[public] class 类名称{ }
类定义有两种形式,分别如下:
- public class:文件名称必须与类名称保持一致,每一个*.java文件中只能够定义一个public class。
- class:文件名称可以和类名称不一致,在一个*.java文件中可以同时定义多个class,并且编译之后会发现不同的类都会保存在不同的*.class文件中。
此处有一个重要的命名约定需要遵守:在定义类名称的时候,每个单词的首字母都必须大写,例如TestJava、HelloDemo。
主方法(main)是一切程序的开始点,主方法的编写形式如下(一定要在类中写):
public static void main(String[] args) { 编写代码语句; }
这是一个主方法(main),它是整个Java程序的入口,所有的程序都是从public static void main(String[]args)开始运行的,这一行的代码格式是固定的。括号内的String[] args不能省掉,如果不写,会导致程序无法执行。String[] args也可以写成String args[],String表示参数args的数据类型为字符串类型,[]表示它是一个数组。
main之前的public static void都是Java的关键字,public表示该方法是公有类型,static表示该方法是静态方法,void表示该方法没有返回值。这些关键字如果现在还不太明白,可以暂时不用深究,现在了解一下即可,在之后的章节中会有更加详细的介绍。
当需要在屏幕上显示数据的时候,就可以使用如下的方法完成:
- 输出之后增加换行:System.out.println(输出内容)。
- 输出之后不增加换行:System.out.print(输出内容)。
【例2-2】(实例文件:ch02\Chap2.2.txt)print与println的区别,观察换行的情况。
public class Test { public static void main(String[] args) { System.out.print("Hello") ; System.out.print(" World ") ; System.out.println(" !!! ") ; System.out.println("你好世界!") ; } }
程序运行结果如图2-2所示。
图2-2 print与println的区别
通过运行结果可以看出,虽然Hello、World和!!!分为3个语句输出,但显示结果还是在一行,说明print在输出之后没有换行,而println在输出之后增加了换行。
2.2 Java基础语法
一个Java程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作。其中,对象是类的一个实例,有状态和行为;类是一个模板,用于描述一类对象的行为和状态;方法是行为,一个类可以有很多方法,例如逻辑运算、数据修改以及所有动作都是在方法中完成的。
2.2.1 基本语法
编写Java程序时,应注意以下几点:
- Java是大小写敏感的,这就意味着标识符Hello与hello是不同的。
- 对于所有的类来说,类名的首字母都应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如MyFirstJavaClass。
- 所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。
- 源文件名必须和类名相同。当保存文件的时候,应该使用类名作为文件名保存(切记Java是大小写敏感的),文件名的后缀为.java。如果文件名和类名不相同则会导致编译错误。
- 所有的Java程序都由public static void main(String []args)方法开始执行。
2.2.2 Java标识符
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。例如,在前面定义的Hello这个类的名称就是一种标识符。在Java中,标识符可以使用字母、数字、_、$进行定义,不能以数字开头,不能是Java的关键字或保留字。
定义的标识符要有意义,例如studentName、School等,这些都是有意义的词。特别要注意的是,标识符不能使用Java的关键字,关键字指的是一些语法结构部分之中有特殊含义的标记。例如,在图2-3中,代码行中用下画线标记的单词都是关键字(在屏幕上这些关键字显示为红色),都不能够作为标识符。
图2-3 关键字和标识符
例如,下面的标识符是合法的:myName1、My_name1、Points1、$points、_my_name、PI、_50c;而下面的标识符是非法的:20name、#name、class、&time、if。
总之,在Java中,标识符的命名有一些规则,这些规则是大家约定俗成的,应该遵守。
- 类和接口名每个单词的首字母大写,例如,MyClass,HelloWorld,Time等。
- 方法名首个单词的首字母小写,其余单词的首字母大写,尽量少用下画线,例如myName、setTime等。这种命名方法叫作驼峰式命名。
- 基本数据类型的常量名全部使用大写字母,单词之间用下画线分隔,例如SIZE_NAME。对象常量可大小混写。
- 变量名可大小写混写,首字母小写,单词间起分隔或连接作用的词(如To、Of)首字母大写。不用下画线,少用美元符号。给变量命名时尽量做到见名知义。
另外,关于Java标识符,还需要注意以下几点:
- 所有的标识符都应该以字母(A~Z或者a~z)、美元符($)或者下画线(_)开始。
- 首字符之后可以是字母(A~Z或者a~z)、美元符($)、下画线(_)或数字的任何字符组合。
- 关键字不能用作标识符。
- 标识符是大小写敏感的,应区分字母的大小写。
2.2.3 Java关键字
表2-1列出了Java的关键字,这些关键字不能用于常量、变量以及任何标识符的名称。
表2-1 Java的关键字
以上的所有关键字都不需要专门地去记,随着代码写熟了,自然就记住了。但是针对以上的关键字,还有几点说明:
- Java的关键字是随新的版本发布而不断变动的,不是一成不变的。
- 所有关键字都是小写的。
- goto和const不是Java编程语言中使用的关键字,它们是Java的保留字,也就是说Java保留了它们,但是没有使用它们。
- 有3个标识符严格来讲不是关键字,可是具备特殊含义:true(真)、false(假)、null(空)。
- 表示类的关键字是class。
2.2.4 Java保留字
Java保留字是为Java预留的关键字,现在还没用到,但是在升级版本中可能作为关键字使用。Java中的保留字为const和goto。
2.2.5 Java分隔符
在Java中,有一类特殊的符号称为分隔符,包括空白分隔符和普通分隔符。空白分隔符包括空格、回车、换行和制表符(Tab键)。空白分隔符的主要作用是分隔标识符,帮助Java编译器理解源程序。例如:
int a;
若标识符int和a之间没有空格,即inta,则编译程序会认为这是用户定义的标识符,但实际上该语句的作用是定义变量a为整型变量。
另外,在编写代码时,适当的空格和缩进可以增强代码的可读性,例如下面这段代码:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello World!"); } }
在这个程序中,用到了大量的用于表示代码语句层次的空白分隔符(主要是制表符和回车),如果不使用这些空白分隔符,这个程序可能会显示如下:
public class HelloWorld{public static void main(String[] args){ System.out.println("Hello World!");} }
与上一个程序相比,这个程序没有使用制表符来做缩排,转行也减少了,显然在层次感上差了很多。甚至还可能是如下情况:
public class HelloWorld{public static void main(String[] args){System.out.println("Hello World!");}}
这个程序将所有的语句都写在同一行上。在语法上,这个程序是正确的,但是在可读性上是非常不好的。因此,在写程序的时候要灵活地使用空白分隔符来分隔语句或者做格式上的缩排。但是,空白分隔符也不能滥用。使用空白分隔符要遵守以下规则:
- 任意两个相邻的标识符之间至少有一个空白分隔符,以便编译程序能够识别。
- 变量名、方法名等标识符不能包含空白分隔符。
- 空白分隔符的多少没有什么含义,一个空白分隔符和多个空白分隔符的作用相同,都是用来实现分隔功能的。
- 空白分隔符不能用普通分隔符替换。
普通分隔符具有确定的语法含义,如表2-2所示。
表2-2 Java的普通分隔符
Eclipse提供了一种简单快速调整程序格式的功能,可以选择Source→Format菜单命令来调整程序格式,如果程序没有错误的话,格式会变成预定义的样式。在程序编写完成后,执行快速格式化,可以使代码美观整齐,应该养成这个习惯。
2.2.6 Java注释
类似于C/C++,Java也支持单行以及多行注释。注释中的字符将被Java编译器忽略。例如,如下一段代码里面具有单行注释与多行注释:
public class HelloWorld { /* 这是第一个Java程序 * 它将打印Hello World * 这是一个多行注释的实例 */ public static void main(String []args){ //这是单行注释的实例 /* 这也是单行注释的实例 */ System.out.println("Hello World"); } }
在给代码添加注释时,程序员需要注意注释的规范,下面介绍几种注释规范。
1.类注释
在每个类前面必须加上类注释,注释模板如下:
/** * Copyright (C), 2006-2010, ChengDu Lovo info. Co., Ltd. * FileName: Test.java * 类的详细说明 * * @author 类创建者姓名 * @Date 创建日期 * @version 1.00 */
2.属性注释
在每个属性前面必须加上属性注释,注释模板如下:
/** 提示信息 */ private String strMsg = null;
3.方法注释
在每个方法前面必须加上方法注释,注释模板如下:
/** * 类方法的详细使用说明 * * @param 参数1 参数1的使用说明 * @return 返回结果的说明 * @throws 异常类型.错误代码 注明从此类方法中抛出异常的说明 */
4.构造方法注释
在每个构造方法前面必须加上注释,注释模板如下:
/** * 构造方法的详细使用说明 * * @param 参数1 参数1的使用说明 * @throws 异常类型.错误代码 注明从此类方法中抛出异常的说明 */
5.方法内部注释
在方法内部使用单行或者多行注释,该注释根据实际情况添加。例如:
//背景颜色 Color bgColor = Color.RED
2.3 数据类型
程序实际上指的就是针对数据的处理流程,那么程序所能够处理的数据的划分就是各个语言的数据类型,在Java中,数据类型分为两大类:基本数据类型和引用数据类型。Java数据类型的划分如图2-4所示。
图2-4 Java数据类型的划分
Java数据类型的默认值如表2-3所示。
表2-3 Java数据类型的默认值
各数据类型的数据范围和占据的内存空间如表2-4所示。
表2-4 数据类型的数据范围和占据的内存空间
下面详细介绍Java的4大类(整型、浮点型、字符型、布尔型)8种基本数据类型以及字符串(String)。
2.3.1 整型
整数类型简称整型,表示的是不带小数点的数字,例如,数字5、100就是整型数据。在Java中,有4种不同类型的整型,分别为byte、short、int和long。默认情况下一个整数的对应类型就是int类型。
每一种数据类型都有其对应数据范围的最大或最小值,如果在计算的过程中超过了此范围,就会产生数据的溢出问题。而要想解决数据的溢出问题,最好的做法是扩大数据范围,例如可以将int类型转换为long类型,转换方法有两种,直接在数据前增加一个“(long)”或者直接在数据后增加一个字母L(大小写均可)。
在Java中,byte类型的数据占据8位内存空间,数值取值范围是-128~127。
【例2-3】(实例文件:ch02\Chap2.3.txt)输出byte类型的最小值与最大值。
public class Test { public static void main(String[] args) { byte byte_min = Byte.MIN_VALUE; //获得byte类型的最小值 byte byte_max = Byte.MAX_VALUE; //获得byte类型的最大值 System.out.println("byte类型的最小值是:"+byte_min); System.out.println("byte类型的最大值是:"+byte_max); } }
程序运行结果如图2-5所示。
图2-5 byte类型的最小值与最大值
short类型数据占据16位内存空间,取值范围是-32768~32767。
【例2-4】(实例文件:ch02\Chap2.4.txt)输出short类型的最小值与最大值。
public class Test { public static void main(String[] args) { short short_min = Short.MIN_VALUE; //获得short类型的最小值 short short_max = Short.MAX_VALUE; //获得short类型的最大值 System.out.println("short类型的最小值是:"+short_min); System.out.println("short类型的最大值是:"+short_max); } }
程序运行结果如图2-6所示。
图2-6 short类型的最小值与最大值
int类型的数据占据32位内存空间,取值范围是-2 147 483 648~2 147 483 647。
【例2-5】(实例文件:ch02\Chap2.5.txt)输出int类型的最小值与最大值。
public class Test { public static void main(String[] args) { int int_min = Integer.MIN_VALUE; //获得int类型的最小值 int int_max = Integer.MAX_VALUE; //获得int类型的最大值 System.out.println("int类型的最小值是:"+int_min); System.out.println("int类型的最大值是:"+int_max); } }
程序运行结果如图2-7所示。
图2-7 int类型的最小值与最大值
long类型的数据占据64位内存空间,取值范围是-9 223 372 036 854 775 808~9 223 372 036 854 775 807。
【例2-6】(实例文件:ch02\Chap2.6.txt)输出long类型的最小值与最大值。
public class Test { public static void main(String[] args) { long long_min = Long.MIN_VALUE; //获得long类型的最小值 long long_max = Long.MAX_VALUE; //获得long类型的最大值 System.out.println("long类型的最小值是:"+long_min); System.out.println("long类型的最大值是:"+long_max); } }
程序运行结果如图2-8所示。
图2-8 long类型的最小值与最大值
2.3.2 浮点型
Java浮点数据类型主要有双精度(double)和单精度(float)两个类型。在Java中,一个小数默认的类型是double,而double类型的范围是最大的。如果定义小数为float类型,为其赋值的时候,必须执行强制转型。有两种转换方式:一种是直接加上字母F(大小写均可),例如“float num = 2.8F ;”;另一种是直接强制转型为float,例如“float num2 = (float) 10.5 ;”。
【例2-7】(实例文件:ch02\Chap2.7.txt)输出float类型的最小值与最大值。
public class Test { public static void main(String[] args) { float float_min = Float.MIN_VALUE; //获得float类型的最小值 float float_max = Float.MAX_VALUE; //获得float类型的最大值 System.out.println("float类型的最小值是:"+float_min); System.out.println("float类型的最大值是:"+float_max); } }
程序运行结果如图2-9所示。
图2-9 float类型的最小值与最大值
【例2-8】(实例文件:ch02\Chap2.8.txt)输出double类型的最小值与最大值。
public class Test { public static void main(String[] args) { double double_min = Double.MIN_VALUE; //获得double类型的最小值 double double_max = Double.MAX_VALUE; //获得double类型的最大值 System.out.println("double类型的最小值是:"+double_min); System.out.println("double类型的最大值是:"+double_max); } }
程序运行结果如图2-10所示。
图2-10 double类型的最小值与最大值
2.3.3 字符型
Java中默认采用的编码方式为UNICODE编码,它是一种十六进制编码方案,可以表示世界上的任意文字信息。所以在Java中字符里面是可以保存中文数据的。在程序中使用单引号‘’声明的数据就称为字符型数据,字符型用char表示,占16位内存空间。
在ASCII码表中,大写字母的ASCII码值范围是65~90,小写字母的ASCII码值范围是97~122,可以发现,对应的大写字母和小写字母ASCII码值的差是32,按照此规律,就可以轻松实现大小写的转换操作。
【例2-9】(实例文件:ch02\Chap2.9.txt)输出字母a的ASCII码值,并将字母a转换为大写。
public class Test { public static void main(String[] args) { char x = 'a'; int y = x; //将字符型赋值给整型 System.out.println(y); //输出字母a的ASCII码值97
//将字母a转换为A,在ASCII码中值相差32,(char)表示将int类型强制转换为char类型 System.out.println((char)(y-32)); } }
程序运行结果如图2-11所示。
图2-11 例2-9的运行结果
2.3.4 布尔型
布尔是一位数学家的名字。布尔型在Java中使用boolean声明,而布尔值的取值只有两个:true、false,一般而言,布尔型数据往往都用于条件判断。但是在这里必须重点强调的是:在一些语言中,例如C语言,把0当作false,而把非0值当作true,可是在Java中,布尔值只有true和false,没有0或者非0值。
【例2-10】(实例文件:ch02\Chap2.10.txt)输出Boolean类型数据。
public class Test { public static void main(String[] args) { boolean t = true; System.out.println("t="+t); } }
程序运行结果如图2-12所示。
图2-12 Boolean类型数据
2.3.5 字符串
字符型只能够包含单个字符,这在很多情况下是无法满足要求的,所以在Java中专门提供了String(字符串)类型。String是引用型数据,是一个类(因此String的首字母一定要大写),但是这个类稍微特殊一些。
对String类型的变量使用“+”,则表示要执行字符串的连接操作。但“+”既可以表示数据的加法操作,也可以表示字符串连接,那么如果这两种操作碰到一起了那么会怎么样呢?如果遇到了字符串,所有其他的数据类型(基本、引用)都会自动变为String型数据。
【例2-11】(实例文件:ch02\Chap2.11.txt)输出字符串类型。
public class Test { public static void main(String[] args) { String s1 = "我爱学"; String s2 = "Java!"; System.out.println(s1+s2); //此处的加号表示连接 } }
程序运行结果如图2-13所示。
图2-13 字符串类型
2.4 数据类型的转换
Java语言是一种强类型的语言。强类型的语言有以下几个要求:
- 变量或常量必须有类型:要求声明变量或常量时必须声明类型,而且只能在声明以后才能使用。
- 赋值时,值的类型必须和变量或常量的类型一致。
- 运算时,参与运算的数据类型必须一致。
但是在实际的使用中,经常需要在不同类型的值之间进行操作,这就需要一种新的语法来适应这种需要,这个语法就是数据类型转换。
在数值处理上,计算机和现实的逻辑不太一样。对于现实来说,1和1.0没有什么区别;但是对于计算机来说,1是整数类型,而1.0是小数类型,其在内存中的存储方式以及占用的空间都不一样,所以类型转换在计算机内部是必须明确地进行的。
Java语言中的数据类型转换有两种:
- 自动类型转换:编译器自动完成类型转换,不需要在程序中编写代码。
- 强制类型转换:强制编译器进行类型转换,必须在程序中编写代码。
由于基本数据类型中boolean类型不是数字型,所以基本数据类型的转换是除了boolean类型以外的其他7种类型之间的转换。下面来具体介绍两种类型转换的规则、适用场合以及使用时需要注意的问题。
2.4.1 自动类型转换
自动类型转换,也称隐式类型转换,是指不需要书写代码,由系统自动完成类型转换。由于实际开发中这样的类型转换很多,所以Java语言在设计时没有为该操作设计语法,而是由JVM自动完成。
有3种可以进行自动类型转换的情况,具体如下:
(1)整数类型之间可以实现转换,如byte类型的数据可以赋值给short、int、long类型的变量,short、char类型的数据可以赋值给int、long类型的变量,int类型的数据可以赋值给long类型的变量。
(2)整数类型转换为float类型,如byte、char、short、int类型的数据可以赋值给float类型的变量。
(3)其他类型转换为double类型,如byte、char、short、int、long、float类型的数据可以赋值给double类型的变量。
在具体转换的过程中,应遵循相应的转换规则,这里的规则为只能从存储范围小的类型转换到存储范围大的类型。具体规则为byte→short(char)→int→long→float→double。
也就是说byte类型的变量可以自动转换为short类型,例如:
byte b=10; short sh=b;
这里在赋值时,JVM首先将b的值转换为short类型,然后再赋值给sh。
另外,在类型转换时可以跳跃。例如:
byte b1=100; int n=b1;
注意:在整数之间进行类型转换时,数值不发生改变,而将整数类型,特别是比较大的整数类型转换成小数类型时,由于存储方式不同,有可能存在数据精度的损失。
【例2-12】(实例文件:ch02\Chap2.12.txt)将int类型转换为float类型,并输出两个数据之和。
public class Test { public static void main(String[] args) { int x = 10; float y = 20.3f; System.out.println(x + y); //int类型的x会自动转换为float类型 } }
程序运行结果如图2-14所示。
图2-14 转换数据类型
2.4.2 强制类型转换
强制类型转换,也称显式类型转换,是指必须书写代码才能完成的类型转换。强制类型转换很可能存在精度的损失,所以必须书写相应的代码,并且能够接受精度损失时才进行强制类型转换。
强制类型转换的规则为从存储范围大的类型转换到存储范围小的类型。具体规则为:double→float→long→int→short(char)→byte。具体的语法格式为(转换到的类型)需要转换的值。
实例代码如下:
double d = 3.10; int n = (int)d;
这里将double类型的变量d强制转换成int类型,然后赋值给变量n。需要说明的是,小数强制转换为整数,采用的是“去1法”,也就是无条件舍弃小数点后的所有数字,因此以上转换的结果是3。int类型的变量转换为byte类型时,则只保留int类型的低8位(也就是最后一个字节)的值。例如:
int n = 123; byte b = (byte)n; int m = 1234; byte b1 = (byte)m;
则b的值还是123,而b1的值为-46。b1的计算方法为:m的值转换为二进制是10011010010,取该数字低8位的值作为b1的值,则b1的二进制值是11010010,按照机器数的规定,最高位是符号位,1代表负数,在计算机中负数存储的是补码,则该负数的原码是10101110,该值就是十进制的-46。
注意:强制类型转换通常都会有精度的损失,所以使用时需要谨慎。
【例2-13】(实例文件:ch02\Chap2.13.txt)将float类型强制转换为int类型,并输出两数之和。
public class Test { public static void main(String[] args) { int x = 10; float y = 20.3f; //x+y的结果是float类型,(int)表示强制转换为int类型 System.out.println((int) (x + y)); } }
程序运行结果如图2-15所示。
图2-15 将float类型强制转换为int类型
2.5 常量与变量
有些数据在程序运行过程中值不能发生改变,有些数据在程序运行过程中值会发生改变,这两种数据在程序中分别被叫作常量和变量。
在实际的程序开发中,可以根据数据在程序运行中是否发生改变来选择应该是使用变量还是常量代表它。
2.5.1 常量
常量就是固定不变的量,一旦被定义,它的值就不能再被改变。声明常量的语法为
final 数据类型 常量名称 [ = 值 ]
常量名称通常使用大写字母,例如PI、YEAR等,但这并不是硬性要求,而只是一个习惯。常量标识符可由任意顺序的大小写字母、数字、下画线(_)和美元符号($)等组成,不能以数字开头,也不能是Java中的保留字和关键字。
当常量用于一个类的成员变量时,必须给常量赋值,否则会出现编译错误。下面是一个常量的应用实例。
【例2-14】(实例文件:ch02\Chap2.14.txt)输出圆周率PI的数值。
public class Test { public static void main(String[] args) { final double PI=3.14159265; System.out.println("圆周率π约等于"+PI); } }
程序运行结果如图2-16所示。
图2-16 输出圆周率PI
注意:Java中的关键字const是保留字,目前并没被Java正式启用,因此不能像C++语言那样使用const来定义常量。
2.5.2 变量
变量代表程序的状态,程序通过改变变量的值来改变整个程序的状态。为了方便引用变量的值,在程序中需要为变量设定一个名称,这就是变量名。例如在3D游戏程序中,人物的位置需要3个变量,分别是x坐标、y坐标和z坐标。在程序运行过程中,这3个变量的值会发生改变。
由于Java语言是一种强类型的语言,所以变量在使用以前必须首先声明数据类型,在程序中声明变量的语法格式如下:
数据类型 变量名称;
例如:
int a;
在该语法格式中,数据类型可以是Java语言中任意的类型,包括前面介绍的基本数据类型以及后续将要介绍的复合数据类型。变量名称是该变量的标识符,需要符合标识符的命名规则,在实际使用中,该名称一般和变量的用途对应,这样便于程序的阅读。数据类型和变量名称之间使用空格进行间隔,空格的个数不限,但是至少需要一个。语句使用“;”作为结束。也可以在声明变量的同时设定该变量的值,语法格式如下:
数据类型 变量名称 = 值;
例如:
int a = 100;
在该语法格式中,=代表赋值,“值”代表具体的数据。注意区别=和==,“==”用于判断是否相等。在该语法格式中,要求值的类型需要和声明变量的数据类型一致。
在程序中,变量的值代表程序的状态,在程序中可以通过变量名称来引用变量的值,也可以为变量重新赋值。例如:
int m = 15; m = 100;
在实际开发过程中,需要声明什么类型的变量,需要声明多少个变量,需要为变量赋什么数值,都根据程序逻辑决定,上面的例子只是为了说明用法。
【例2-15】(实例文件:ch02\Chap2.15.txt)输出变量x的数值。
public class Test { public static void main(String[] args) { int x = 10; //声明变量x为int类型,并赋值为10 x = 20; //改变变量x的值为20 System.out.println("x="+x); } }
程序运行结果如图2-17所示。
图2-17 输出变量x的数值
2.5.3 变量的作用域
在Java中,变量的作用域分为4个级别:类级、对象实例级、方法级、块级。类级变量又称全局变量或静态变量,需要使用static关键字修饰。类级变量在类定义后就已经存在,占用内存空间,可以通过类名来访问,不需要实例化。对象实例级变量就是成员变量,实例化后才会分配内存空间,也才能访问。方法级变量就是在方法内部定义的变量,又称局部变量。
在定义变量时,还需要注意以下几点:
- 方法内部除了能访问方法级变量,还可以访问类级和对象实例级变量。
- 块内部能够访问类级、对象实例级变量。如果块被包含在方法内部,它还可以访问方法级变量。
- 方法级和块级变量必须显式地初始化,否则不能访问。
【例2-16】(实例文件:ch02\Chap2.16.txt)变量作用域应用实例。
程序运行结果如图2-18所示。
图2-18 变量作用域
通过这个例子可以看出,变量在不同的地方起作用的范围也是不同的。块中定义的变量是局部变量,不能被外部调用。
2.6 Java的运算符
计算机程序是由许多语句组成的,而语句是由更基本的表达式和运算符组成的。计算机最基本的用途之一就是执行数学运算,作为一门计算机语言,Java也提供了一套丰富的运算符来操纵变量。可以把运算符分成以下几种:
- 算术运算符。
- 自增自减运算符。
- 关系运算符。
- 逻辑运算符。
- 赋值运算符。
- 条件运算符。
- 位运算符。
下面分别介绍各种运算符的使用。
2.6.1 算术运算符
算术运算符用在数学表达式中,它们的作用和在数学中的作用基本一样。算术运算符的含义及应用实例如表2-5所示。表格中的实例假设整数变量A的值为10,变量B的值为20。
表2-5 算术运算符的含义及应用实例
【例2-17】(实例文件:ch02\Chap2.17.txt)下面的简单实例程序演示了算术运算符的用法。
程序运行结果如图2-19所示。
图2-19 算术运算符
2.6.2 自增自减运算符
自增(++)和自减(--)是两个特殊的算术运算符,大多数算术运算符需要两个操作数来进行运算,而自增自减运算符只需要一个操作数。自增自减运算符的含义及应用实例如表2-6所示。表格中的实例假设整数变量A的值为10,变量B的值为20。
表2-6 自增自减运算符的含义及应用实例
【例2-18】(实例文件:ch02\Chap2.18.txt)自增运算++a应用实例。
public class Test { public static void main(String[] args) { int a = 10; int b = 20; b = ++a; System.out.println("a=" +a+ ",b="+b); } }
程序运行结果如图2-20所示。通过结果可以看到,b=++a是a先加1,然后把结果赋予b。
图2-20 自增运算++a
【例2-19】(实例文件:ch02\Chap2.19.txt)自增运算a++应用实例。
public class Test { public static void main(String[] args) { int a = 10; int b = 20; b = a++; System.out.println("a="+a+", b="+b); } }
程序运行结果如图2-21所示。通过结果可以看到,b=a++是先将a的值赋予b,然后a再加1。
图2-21 自增运算a++
总之,b=a++或者b=++a,对a来说最后的结果都是自加1,但对b来说结果就不一样了。通过这两个例子,希望读者能够明白a++和++a的区别。a--和--a的情况与此类似。
2.6.3 关系运算符
关系运算符也称为比较运算符,用于对两个操作数进行关系运算,以确定两个操作数之间的关系。常用的关系运算符的含义及应用实例如表2-7所示。表中的实例假设整数变量A的值为10,变量B的值为20。
表2-7 关系运算符的含义及应用实例
【例2-20】(实例文件:ch02\Chap2.20.txt)输出两个数的比较结果。
public class Test { public static void main(String[] args) { int a = 10, b = 20; if (a > b) { System.out.println("a>b"); } if (a < b) { System.out.println("a<b"); } if (a == b) { System.out.println("a=b"); } } }
程序运行结果如图2-22所示。在上述程序中,首先定义了a和b的数据类型为int类型,并进行了赋值。通过if语句判断a和b的大小关系,一共有3种关系——大于、小于或等于,并将结果显示出来。因为a=10,b=20,因此最后结果是a<b。
图2-22 关系运算符实例
注意:如果要判断两个变量是否相等,不是使用=,而是使用==。=表示赋值,==表示判断,这是一个非常容易出错的地方,读者应该特别注意。
2.6.4 逻辑运算符
逻辑运算符主要用来把各个运算的变量连接起来,组成一个逻辑表达式,以判断某个表达式是否成立,判断的结果是true或false。逻辑运算符的含义及应用实例如表2-8所示。表中的实例假设布尔变量A为真,B为假。
表2-8 逻辑运算符的含义及应用实例
【例2-21】(实例文件:ch02\Chap2.21.txt)逻辑运算符!应用实例。
public class Test { public static void main(String[] args) { boolean flag = true; System.out.println(!flag); } }
程序运行结果如图2-23所示。上述代码中,首先定义flag为布尔型,并赋值为true,通过逻辑非运算符将flag的值改变为false。
图2-23 逻辑非运算符实例
逻辑运算符的重点是与和或两种运算,它们各有两组不同的实现。与操作的特点是若干个条件都要同时满足,若有一个条件不满足,则最终的结果就是false。在Java中与操作分为两种不同的形式——&和&&,下面举例说明。
【例2-22】(实例文件:ch02\Chap2.22.txt)&应用实例。
public class Test { public static void main(String[] args) { if (1 == 2 & 1 / 0 == 0) {//false & 错误 System.out.println("条件满足!") ; } } }
程序运行结果如图2-24所示。运行后发现代码出现了错误,提示除数为0。这说明1==2和1/0==0这两个条件都进行了判断,即使第一个条件1==2已经不成立,也会继续判断第二个条件是否成立。但这是没有必要的,因为只要有一个条件是false,那么即使后面的条件都成立,最终结果也是false。
图2-24 &应用实例
上述实例说明&会将所有的判断条件都加以验证。下面使用与运算的另外一种形式——&&。
【例2-23】(实例文件:ch02\Chap2.23.txt)&&应用实例。
public class Test { public static void main(String[] args) { if (1 == 2 && 1 / 0 == 0) { System.out.println("条件满足!") ; } } }
程序运行结果如图2-25所示。在上述代码中,与运算符为&&,运行结果没有出错,但也没有任何显示。这说明在判断完1==2条件为false后,就终止了后面的判断,if的条件表达式的最终结果为false。这说明&&只要判断某个条件为false,不管后面有多少个条件都不再进行判断,最终结果就是false。
图2-25 &&应用实例
或运算的若干个条件有一个满足即可,或运算符两种:|和||。
【例2-24】(实例文件:ch02\Chap2.24.txt)|应用实例。
public class Test { public static void main(String[] args) { if (1 == 1 | 1 / 0 == 0) { System.out.println("条件满足!") ; } } }
程序运行结果如图2-26所示。现在所有的判断条件都执行了,所以造成了错误。
事实上,对于或运算,有一个条件返回true,后面不管有多少个true或false,最终结果都肯定是true,所以这样的操作可以采用||完成。
图2-26 |应用实例
【例2-25】(实例文件:ch02\Chap2.25.txt)||应用实例。
public class Test { public static void main(String[] args) { if (1 == 1 ||1 / 0 == 0) { System.out.println("条件满足!") ; } } }
程序运行结果如图2-27所示,说明没有判断1/0==0这个条件。||运算符判断有一个条件是true,所有后面的条件就不再进行判断,最终结果就是true。
图2-27 ||应用实例
2.6.5 赋值运算符
赋值运算符的主要功能是为各种不同类型的变量赋值,简单的赋值运算由等号(=)来实现,就是把等号右边的值赋予等号左边的变量。例如:
int x = 2048;
要注意=与==的不同。
在Java中,赋值运算符包括基本赋值运算符(=)和复合赋值运算符。复合赋值运算符是在基本赋值运算符的基础上,结合算术运算符而形成的具有特殊意义的赋值运算符。赋值运算符及其应用实例如表2-9所示。
表2-9 赋值运算符及其应用实例
【例2-26】(实例文件:ch02\Chap2.26.txt)赋值运算符应用实例。
public class Test { public static void main(String[] args) { int a = 10; int b = 20; System.out.println("a=" + a + ", b=" + b); a += b; //a+=b 相当于 a = a+b System.out.println("a += b, a=" + a); } }
程序运行结果如图2-28所示。
图2-28 赋值运算符应用实例
2.6.6 条件运算符
条件运算符(?:)也称为三元运算符。语法形式如下:
布尔表达式?表达式1:表达式2
其运算过程为:如果布尔表达式的值为true,则返回表达式1的值;否则返回表达式2的值。
【例2-27】(实例文件:ch02\Chap2.27.txt)条件运算符应用实例。
public class Test { public static void main(String[] args) { int score = 68; String mark = (score >= 60) ? "及格" : "不及格"; System.out.println("考试成绩结果:" + mark); } }
程序运行结果如图2-29所示。在上述代码中,首先定义score为int类型,赋值68,通过比较,score>=60这个条件成立,结果为真,这样会返回“及格”。如果定义score为50,则score>=60这个条件不成立,结果为假,这样会返回“不及格”。
提示:条件运算也可以转换为if语句,其实它就是if语句的简写版本。读者如果觉得掌握条件运算有困难,也可以改写为if语句,但阅读代码中的条件运算符时应该能够理解其含义。
图2-29 条件运算符应用实例
2.6.7 位运算符
位运算符主要用来对操作数的每个二进制位进行运算,其操作数的类型是整数类型以及字符型,运算的结果是整数类型。位运算符的含义及实例如表2-10所示。
表2-10 位运算符及其实例
【例2-28】(实例文件:ch02\Chap2.28.txt)位运算符应用实例。
public class Test { public static void main(String[] args) { int a = 10; int b = 20; int c = 3; c <<= 2 ; System.out.println("c <<= 2 = " + c ); c >>= 2 ; System.out.println("c >>= 2 = " + c ); c >>= 2 ; System.out.println("c >>= a = " + c ); c &= a ; System.out.println("c &= 2 = " + c ); c ^= a ; System.out.println("c ^= a = " + c ); c |= a ; System.out.println("c |= a = " + c ); } }
程序运行结果如图2-30所示。
图2-30 位运算符应用实例
2.6.8 优先级与结合性
如果多个运算符出现在一个表达式中,怎么样确定运算次序呢?这就涉及运算符的优先级的问题。在一个包含了多个运算符的表达式中,运算符优先级不同会导致最后得出的结果差别甚大。
例如,(1+3)+(3+2)*2,这个表达式如果按加号最优先计算,答案是18,如果按照乘号最优先,答案则是14。再如,x = 7 + 3 * 2;,这里x得到13,而不是20,因为乘法运算符比加法运算符有更高的优先级,所以先计算3 * 2得到6,然后再加7。
在表2-11中,最高优先级的运算符在表的最上面,最低优先级的运算符在表的最下面。
表2-11 Java运算符的优先级
2.7 就业面试解析与技巧
2.7.1 面试解析与技巧(一)
面试官:Java中有没有goto?
应聘者:goto是Java中的保留字,但目前Java并没用启用goto。
2.7.2 面试解析与技巧(二)
面试官:String是基本数据类型吗?
应聘者:基本数据类型包括byte、short、int、long、char、float、double和boolean。String不是基本数据类型,而是引用数据类型,其本质是一个类,因此String的首字母应该大写。