java程序基础入门
第1章 认识java
Java是一种面向对象的程序设计语言,由Sun公司的James Gosling等人于20世纪90年代初开发。它最初被命名为Oak,用来开发消费类电子产品,解决诸如电话、电视机等家用电器的控制和通讯问题。后来随着互联网的发展,Sun看到了Oak在计算机网络上的广阔应用前景,于是改造了Oak,在1995年5月正式命名为"Java"。
后来 Sun 公司被 Oracle (甲骨文)公司收购,Java 也随之成为 Oracle 公司的产品。
2005 年 6 月,JavaOne 大会召开,SUN 公司公开 Java SE 6。此时,Java 的各种版本已经更名,以取消其中的数字 “2”:J2EE 更名为 Java EE,J2SE 更名为Java SE,J2ME 更名为 Java ME。
版本变化:
1995年5月23日,Java语言诞生
1996年1月 JDK1.0
1997年2月 JDK1.1
1998年12月 JDK1.2(将Java分成了J2SE,J2EE,J2ME)
2000年5月 J2SE1.3
2002年2月 J2SE1.4(1.4.2版本很多公司在使用)
2004年10月 JDK1.5(改名JavaSE5.0,JavaEE,JavaME)
2006年12月 JavaSE6.0
2009年04月20日,甲骨文(Oracle)74亿美元收购Sun。
2011年7月 JavaSE7.0(市场主流版本)
2014年3月 JavaSE8.0
2017年9月 JavaSE9.0
Java分为三个体系:
JavaSE(J2SE)(Java2 Platform Standard Edition,java平台标准版),
是为开发普通桌面和商务应用程序提供的解决方案,JavaSE是三个平台最核心的部分,JavaEE和JavaME都是从JavaSE的基础上发展而来的,JavaSE平台包括了Java最核心的类库,包括,如集合,IO,数据库连接以及网络编程等。
JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平台企业版),为了开发企业级应用程序提供的解决方案。JavaEE可以被看做一个技术平台,该平台用于开发、装配以及部署企业及应用程序,其中主要包括Servlet、JSP、JavaBean、JDBC、EJB、WebService等技术。
JavaME(J2ME)(Java 2 Platform Micro Edition,java平台微型版)。是为了开发电子消费产品和嵌入式设备提供的解决方案。JavaME主要用于小型数字电子设备上的软件程序的开发。例如,为家用电器增加智能化控制和联网功能,为手机增加新的游戏和通讯录管理功能。此外,JavaME提供了HHTTP等高级Internet协议,是移动电话能以Client/Server方式直接访问Internet的全部信息,提供最高效率的无线交流。
Java语言的特点
Java 语言是简单的:
Java 语言的语法与 C 语言和 C++ 语言很接近,使得大多数程序员很容易学习和使用。另一方面,Java 丢弃了 C++ 中很少使用的、很难理解的、令人迷惑的那些特性,如操作符重载、多继承、自动的强制类型转换。特别地,Java 语言不使用指针,而是引用。并提供了自动分配和回收内存空间,使得程序员不必为内存管理而担忧。
1.面向对象:
Java 语言提供类、接口和继承等面向对象的特性,为了简单起见,只支持类之间的单继承,但支持接口之间的多继承,并支持类与接口之间的实现机制(关键字为 implements)。Java 语言全面支持动态绑定,而 C++语言只对虚函数使用动态绑定。总之,Java语言是一个纯的面向对象程序设计语言。
2.分布式:
Java设计成支持在网络上应用,它是分布式语言,Java既支持各种层次的网络连接,又以Socket类支持可靠的流(steam)网络连接,所以用户可以产生分布式的客户机和服务器。
网络变成软件应用的分布运载工具。Java程序只需编写一次,就可到处运行。
3.健壮性:
Java 的强类型机制、异常处理、垃圾的自动收集等是 Java 程序健壮性的重要保证。对指针的丢弃是 Java 的明智选择。Java 的安全检查机制使得 Java 更具健壮性。
4.安全性:
Java的存储分配模型是它防御恶意代码的主要方法之一。Java没有指针,所以程序员不能得到隐蔽起来的内幕和伪造指针去指向存储器。更重要的是,Java编译程序不处理存储安排决策,所以程序员不能通过查看声明去猜测类的实际存储安排。编译的Java代码中存储引用在运行时由Java解释程序决定实际存储地址。
Java运行系统使用字节码验证过程保证装载到网络上的代码不违背任何Java语言限制。这个安全机制部分包括类如何从网上装载。例如,装载的类是放在分开的名字空间而不是局部类,预防恶意的小应用程序用它自己的版本来代替标准Java类。
Java语言不支持指针,一切对内存的访问都必须通过对象的实例变量来实现,从而使应用更安全。
5.体系结构中立:
Java 程序(后缀为 java 的文件)在 Java 平台上被编译为体系结构中立的字节码格式(后缀为 class 的文件),然后可以在实现这个 Java 平台的任何系统中运行。这种途径适合于异构的网络环境和软件的分发。
6.可移植:
这种可移植性来源于体系结构中立性,另外,Java 还严格规定了各个基本数据类型的长度。Java 系统本身也具有很强的可移植性,Java 编译器是用 Java 实现的,Java 的运行环境是用 ANSI C 实现的。
7.解释型:
如前所述,Java 程序在 Java 平台上被编译为字节码格式,然后可以在实现这个 Java 平台的任何系统中运行。在运行时,Java 平台中的 Java 解释器对这些字节码进行解释执行,执行过程中需要的类在联接阶段被载入到运行环境中。
8.高性能:
Java是一种先编译后解释的语言,所以他不如全编译性语言快。但是有些情况下性能是很要紧的,为了支持这些情况,Java设计者制作了“及时”编译程序,它能在运行时吧Java字节码翻译成特定CPU(中央处理器)的机器代码,也就是实现全编译了。
Java字节码格式设计时考虑到这些“及时”编译程序的需要,所以生成机器代码的过程相当简单,它能产生相当好的代码。
9.多线程:
所谓的多线程可以简单地理解为程序中有多个任务可以并发执行,这样可以在很大程度上提高程序的执行效率。
10.Java 语言是动态的:
Java 语言的设计目标之一是适应于动态变化的环境。Java 程序需要的类能够动态地被载入到运行环境,也可以通过网络来载入所需要的类。这也有利于软件的升级。另外,Java 中的类有一个运行时刻的表示,能进行运行时刻的类型检查。
1.1 Windows系统Java开发环境搭建
1.1.1下载安装JDK
首先,下载地址:https://www.oracle.com/java/technologies/downloads/,在下载页面中根据自己的系统选择对应的版本,本文以 Window 64位系统为例:
可以选择最新版(一般不推荐)
推荐JDK 8/12 为当前稳定版
下载 JDK 后进行安装和配置,还有安装 JDK 的时候也会安装 JRE,一并安装就可以了。
安装JDK,安装过程中可以自定义安装目录等信息。
安装步骤如下图:
安装完成目录如下:
bin目录:该目录存放一些可执行程序。如javac.exe (Java编译器)、java.exe (Java运行工具)、jar.exe (打包工具)和javadoc.exe (文档生成工具)等。
db目录:db目录是一个小型的数据库。从JDK6开始,Java中引入了一个新的成员Java DB,这是一个纯Java实现、开源的数据库管理系统。这个数据库不仅很轻便,而且支持JDBC4.0所有的规范,在学习JDBC时,可以选择直接使用Java DB即可。
include目录:.h头文件,C语言开发时用到的头文件。比如jni.h是开发jni程序时必须引用的头文件。
jre目录:该目录是Java运行时环境的根目录。它包含Java虚拟机,运行时的类包、Java应用启动器以及一个bin目录,但不包含开发环境中的开发工具。
lib目录:包含lib包文件。lib是library的缩写,意为Java类库或库文件,是开发工具使用的归档包文,我们经常看到的dt.jar和tools.jar就在这个目录下。
javafx-src.zip:该压缩文件内存放的是Java FX(Java图形用户界面工具)所有核心类库的源代码。
src.zip:放置的是JDK核心类的源代码,通过该文件可以查看Java基础类的源代码。
README等:说明性文档。
1.1.2 环境变量配置
以win10系统为例:
右击『我的电脑』-> 选择『属性』->选择『高级系统设置』->打开『系统属性』选项框->选择『高级』选项卡->选择『环境变量』
在 “系统变量” 中设置 path项属性,在path环境变量中添加“jdk安装路径\bin”。
测试JDK是否安装成功
“开始”->“运行”,键入"cmd";
键入命令: java -version、java、javac 几个命令,出现以下信息,说明环境变量配置成功
1.2 Java运行及原理分析
1.2.1 第一个java源文件
Java应用程序的编写及执行流程如下:
1.源文件:编写Java源文件(我们也称之为源代码文件),它的扩展名为.java
2.编译:然后通过编译器把源文件编译成字节码文件,字节码文件扩展名为.class。
3.运行:最后使用解释器来运行字节码文件。
下面通过编写HelloWorld程序进行讲解。
第一步:编辑源文件。
在指定盘(比如D盘)新建一个test文件夹,并在该文件夹中新建一个文本文档,重命名为HelloWorld.java后,用记事本方式打开,在其中编写如下一段Java代码,然后保存。
public class HelloWorld{//类声明
public static void main(String args[]){//主函数
System.out.println (“HelloWorld!”);//输出helloworld
}
}
说明:
1、所有Java源文件的扩展名必须为.java。
1、class是一个关键字,用于定义一个类。在Java中,类是程序的基本单元,所有的代码都需要写在类中。
2、HelloWorld是类的名称,简称类名,类名必须和文件名相同。class关键字与类名之间需要用空格、制表符、换行符等任意的空白字符进行分隔。类名之后要写一对大括号,它定义了当前这个类的管辖范围。
3、“public static void main(String[] args){}”定义了一个main()方法,该方法是Java程序的执行入口,程序将从main()方法所属大括号内的代码开始执行。
4、在main()方法中编写了一条执行语句“System.out.println(“Hello World!”);”,它的作用是打印一段文本信息,执行完这条语句会在命令行窗口中打印“Hello World!”
1.2.2 编译运行
1、单击“开始菜单->所有程序->附件->运行”(或者使用快捷键Win+R),在运行窗口中输入“cmd”并确定后,将打开命令行窗口。在命令行窗口输入如下两行命令进入源文件目录。
F: --切换到F盘根目录
2、在命令行窗口中输入“javac HelloWorld.java”命令,对源文件进行编译。
上面的javac命令执行完毕后,会在当前目录下生成一个字节码文件“HelloWorld.class”。
注意:编译文件时,会出现“找不到文件”的错误。该错误有可能是因为文件的扩展名被隐藏了,虽然文本文件被重命名为“HelloWorld.java”,但实际上该文件的真实文件名为“HelloWorld.java.txt”,文件类型并没有得到修改。解决方式是打开Windows系统控制面板中的【文件夹选项】,在“查看”选项下高级设置一栏中将“文件扩展名”选项前面标记上“√”即可。
第三步:运行编译后的字节码文件。
如果编译正确执行后,在命令行窗口中输入“java HelloWorld”命令,运行编译好的字节码文件,将会在控制台上输出“Hello World!”。
1.2.3 Java程序工作原理
JAVA的工作原理是:“一处编译,到处运行"。(.java源文件,必须编译成.class文件,在各种java平台层都可以运行)
Java程序是运行在Java虚拟机上的,Java虚拟机英文缩写为JVM:Java Virtual Machine ,虚拟机是一个虚构出来的计算机,有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。
Java虚拟机屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码文件(字节码文件),就可以在多种平台上不加修改地运行。
Java程序的运行机制如下图所示:
硬件层:就是没有任何操作系统的计算机主要是指我们的硬件(主机,显示器等)。
操作系统层:是指我们的windows\linux\unix\android\ios等
JAVA平台层:针对不同的操作系统JAVA提供了不同的虚拟机
应用平台层:各种JAVA应用程序(如:QQ、百度视频等)、JAVA-WEB程序(12306、QQ空间等):
编译源文件:java源代码被java编译器编译(Compile)。如果这时产生错误,我们称为编译错误。如果没有错误,则生成字节码(byte code)。
运行字节码:这里,java字节码被装载到java虚拟机中,解释成本地代码再运行。如果此时产生错误,我们称之为运行时错误(Runtime)。
1.3 java基础语法
Java 标识符
Java 所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
关于 Java 标识符,有以下几点需要注意:
大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的
Java标识符由数字,字母和下划线(_),美元符号(
)组成。在
J
a
v
a
中是区分大小写的,而且还要求首位不能是数字。长度没有限制。最重要的是
J
a
v
a
关键字不能当作
J
a
v
a
标识符合法标识符举例:
a
g
e
、
)组成。 在Java中是区分大小写的,而且还要求首位不能是数字。长度没有限制。最重要的是Java关键字不能当作Java标识符 合法标识符举例:age、
)组成。在Java中是区分大小写的,而且还要求首位不能是数字。长度没有限制。最重要的是Java关键字不能当作Java标识符合法标识符举例:age、salary、_value、__1_value
非法标识符举例:123abc、-salary
针对Java当中的不同内容,在标识符的基础上,为这些内容命名还要符合以下规定,但是这些规定是不受语法约束的。
1、包名:多单词组成时所有字母均小写,使用.连接 aaa.bbb.ccc
2、类名&接口名:大驼峰式 AaaBbbCcc
3、变量名&方法名:小驼峰式 aaaBbbCcc
4、常量名:多单词组成是所有字母均大写,使用_连接 AAA_BBB_CCC
注释
任何一门编程语言都有注释,通过注释可以提高程序的可读性,使程序的条理更加清晰,注释是对书籍或文章的语汇、内容、背景、引文作介绍、评议的文字。在JAVA程序中,我们为了方便程序员自己对代码的理解,在程序交接后,更快的读取识别别人的代码,我们会为我们的程序加入注释,注释并不会影响代码的运行。
用来解释和说明程序的文字。案例中的代码我们并不知道什么意思,我们可以使用注释来提醒自己我的代码的功能是什么。注释是不会被执行的。
格式:
单行注释 //注释内容
多行注释 /注释内容/
文档注释 /注释内容/
注释的进一步解释
对于单行和多行注释,被注释的文字,不会被JVM解释执行。
对于文档注释,是java特有的注释,其中注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档。在文档注释中可以使用注解配合javadoc完成对信息的进一步说明。
注释是一个程序员必须要具有的良好编程习惯。便于自己日后的代码维护,也方便别人阅读你的代码。
HelloWorld注释示例:
/*
class:类,Java当中组织代码的基本单位
HelloWorld:类名,可自定义,必须与文件名一致
public:访问权限修饰符,现为固定写法
static:静态修饰符,现为固定写法
void:返回值类型,现为固定写法
main:方法名,现为固定写法
String[]:参数类型,现为固定写法
args:参数名,可以自定义修改,建议固定写为args
/
public class HelloWorld {
/
main方法是程序入口,即JVM从main方法处开始运行程序。
*/
public static void main(String[] args) {
//打印语句
//小括号内为打印字符串语句,字符串必须使用""包裹
System.out.println(“Hello World!”);
}
}
关键字和保留字
关键字是对Java的编译器有特殊的意义,他们用来表示一种数据类型,或者表示程序的结构等;
保留字是为Java预留的关键字,虽然现在没有作为关键字,但在以后的升级版本中有可能作为关键字,goto与const是Java中的保留字。
1.4 本章小结
课后练习:
一、认识java
1、JAVA之父是( B )
A、史蒂夫·乔布斯 B、詹姆斯·高斯林 C、比尔·盖茨 D、丹尼斯·里奇
2、JAVAEE是什么版本( A )
A、企业版 B、标准版 C、微型版 D.商务版
3、通过Java语言编写的应用程序在不同的系统平台上都可以运行,这是JAVA的( C )
A、穿越性 B、跨越性 C、跨平台性 D、多平台性
4、JAVA的特性是( B )
A、多处编译一处运行 B、一处编译到处运行
C、多处编译到处运行 D、一处编译一处运行
5、java通过编译器之后生成的文件叫做( B )
A、源文件 B、字节码文件 C、编译文件 D、程序文件
6、2004年9月30日,( B )发布,成为Java语言发展史上的又一里程碑。
A、Java SE 6 B、J2SE1.4 C、J2SE1.5 C、JDK1.6
7、Java源文件的后缀是( C )
A、.class B、.javac C、.java D、.txt
8、JRE(Java Runtime Environment ) 是Java的( B )
A、开发工具包 B、运行环境 C、编译器 D、解释器
9、其中不是JAVA应用模型的是( B )
A、JavaSE B、JavaMM C、JavaME D、JavaEE
10、JAVA最新的版本是( C )
A、jdk8 B、jdk9 C、jdk19 D、jdk11
二、Java基础语法
1、那一个不是注释符号( D )
A、// B、/* / C、/** */ D、#
2、常见的关键字有( C )
A、public B、static C、main D、void
3、不是标识符特点的是( A )
A、标识符最长为100字符 B、标识符没有长度限制
C、标识符区分大小写 D、标识符首字符不能是数字
4、下面合法的标识符是( A )
A、main B、*main C、1_main D、姓名
5、下面不合法的标识符是( D )
A、abc B、ABC C、_ABC D、a bc
6、关键字的特点是( B )
A、有特定的字符
B、全部都是小写的单词,有特殊含义
C、全部都是大写的单词,有特殊含义
D、可以用来完成标识符的命名
7、那一个选项不是标识符的命名规则( D )
A、不能以数字开头
B、由字母,数字、下划线和$组成
C、区分大小写
D、用来表示某些特殊字符的符号
8、下面不合法的标识符是( D )
A、abcAbc B、ABC_ABC C、AbcAbc D、1_ABC
第2章 变量&运算符
2.1 变量的概念和作用
变量(variable)是用来存储数据的一块存储区域,在程序运行中它的值可以发生变化。变量可以存放一种数据类型的值,Java程序在运行加载时会根据变量的不同数据类型来分配不同的内存空间,变量的数据类型在声明时指定。
变量是指在程序的运行过程中随时可以发生变化的量,作用是:
1.变量是程序中数据的临时存放场所
2.保存程序运行时用户输入的数据
3.特定的运算结果等
2.1.1 声明变量
变量是用来描述一条信息的别名,可以在程序代码中使用一个或多个变量。变量中可以存储各种类型的信息,如登录信息、版本名称、文件的大小、某个英文单词以及飞机票价格等。
在 java 中变量的基本语法如下所示:
数据类型 变量名 = 变量值;
DataType identifier;
DataType identifier=value;
上述语法代码中涉及 3 个内容:DataType、 identifier 和 value,其具体说明如下:
DataType:变量类型,如 int、string、 char 和 double 等。
identifier:标识符,也叫变量名称。
value:声明变量时的值
示例代码:
String employee; // String 类型的变量
boolean isSave; // boolean 类型的变量
int create_at; // int 类型的变量
2.1.2 变量赋值
char usersex=‘女’; // 直接赋值
String username; // 先声明
username =“琪琪”; // 后赋值
tring username,address,phone,tel; // 声明多个变量
int num1=12,num2=23,result=35; // 声明并初始化多个变量
注意:
Java 中初始化变量时需要注意以下事项:
变量是类或者结构中的字段,如果没有显式地初始化,默认状态下创建变量并默认初始值为 0。
方法中的变量必须显式地初始化,否则在使用该变量时就会出错。
2.2常量
常量是不能改变的量,即每一个常量就是一个数值,常量可区分为不同的类型,如:25、0、-8为整型常量,6.8、-7.89为实型常量,‘a’、‘b’为字符常量。常量一般从其字面形式即可判断。这种常量称为字面常量或直接常量。
整型常数:
(1)十进制表示方式:正常数字,如 13、25等
(2)二进制表示方式:以0b(0B)开头,如0b1011 、0B1001
(3)十六进制表示方式:以0x(0X)开头,数字以0-9及A-F组成,如0x23A2、0xa、0x10
(4)八进制表示方式:以0开头,如01、07、0721
浮点常数:
如2.13、1.0
布尔常数:
用来表示是否,布尔类型只有两个值 true代表真即满足条件
false代表假即不满足条件
字符常数:
A.普通字符:
(1)表示单个字符,键盘的按键可以输入一个字符。中文的一个汉字可以代表一个字符。
(2)字符需要使用’’将内容包裹
(3)字符内容不能为空
如 ‘1’、 ‘a’、 ‘ ’(空格)、 ‘中’、 ‘$’
B.转义字符:
有时我们无法直接给出一个字符,需要使用转义字符进行转义动作。转义字符也为一个字符,由转义符号与被转义字符组成
转义符号:\ ,转义常量如下表:
转义字符 意义 ASCII码值(十进制)
la 响铃(BEL) 007
\b 退格(BS),将当前位置移到前一列 008
W 换页(FF),将当前位置移到下页开头 012
In 换行(LF),将当前位置移到下一行开头 010
Ir 回车(CR),将当前位置移到本行开头 013
At 水平制表(HT)(跳到下一个TAB位置) 009
IW 垂直制表(VT) 011
代表一个反斜线字符"V 092
Y’ 代表一个单引号(撇号)字符 039
" 代表一个双引号字符 034
? 代表一个问号 063
10 空字符(NULL) 000
A000 1到3位八进制数所代表的任意字符 三位八进制
(xhh 1到2位十六进制所代表的任意字符 二位十六进制
字符串常量:
(1)字符串String是一种特殊的数据类型
(2)字符串必须使用“”包裹
如 “我爱Java”、 “0”、 “a”、 “”、 “null”
Null常量:
在面向对象的时候使用,他表示的是值为null,并不是没有,只有一个值,主要用来争对于引用数据类型。【null】
符号常量:
用final修饰的变量是符号常量,格式:final 变量类型 变量名(大写)=初始化值;
比如:我们的姓名,取好名字后我们基本上是不会去改变的,但名字又会被经常使用,所有我们可以定义为符号常量。
final double PI=3.1415926;//定义了一个符号常量PI,3.1415926
常量语法:
在Java中,常量用关键字final来表示(在后面章节会详细讲解),语法如下:
final数据类型 常量名 = 初始值;
提示:
常量在声明的时候必须初始化;
常量在初始化后值不能再更改,否则会引起错误。
例如:
final double PI = 3.14;
常量示例代码:
/*
常量:固定不变的数
整数,小数,字符,布尔,字符串
*/
public class ConstDemo{
public static void main(String[] args){
//整数
//十进制:常用
System.out.println(8);
//二进制:以0b/0B开头 只包含0和1
System.out.println(0b1000);
//十六进制:以0x/0X开头 0-9 a-f
System.out.println(0x8);
System.out.println(0xb);
//八进制:以0开头 0-7
System.out.println(010);//8
System.out.println(011);//9
System.out.println(017);//15
//小数
System.out.println(3.1415926);
//布尔
System.out.println(true);
System.out.println(false);
//字符 必须用’‘包裹起来 不能为空
System.out.println(‘1’);
System.out.println(‘a’);
System.out.println(‘B’);
System.out.println(‘家’);
System.out.println(’&‘);
System.out.println(’ ');
//System.out.println(‘10’);//错误: 未结束的字符文字
//字符串 必须用"“包裹起来
System.out.println(“我想有一个女同桌!”);
System.out.println(”");
}
}
2.3 数据类型
Java是一种强类型语言,对不同数据结构进行了严格的区分,对每一种数据类型都做了明确定义,也同时规定了每一种数据类型的变量在内存中占用空间的大小。
数据类型分为基本类型与引用类型,引用类型包括:数组、类、接口,在面向对象后期会全部介绍完毕:
2.3.1 基本数据类型
基本数据类型包括 boolean(布尔型)、float(单精度浮点型)、char(字符型)、byte(字节型)、short(短整型)、int(整型)、long(长整型)和 double (双精度浮点型)共 8 种,详见表所示。
1.整数型:
类型 关键字 内存 取值范围
字节型 Byte 1字节 -128~127
短整型 short 2 字节 -32768~32767
整型 int 4 字节 -2147483648~2147483647
长整型 long 8 字节 -9223372036854775808L~9223372036854775807L
byte 类型是最小的整数类型。当用户从网络或文件中处理数据流时,或者处理可能与 Java 的其他内置类型不直接兼容的未加工的二进制数据时,该类型非常有用。
short 类型限制数据的存储为先高字节,后低字节,这样在某些机器中会出错,因此该类型很少被使用。
int 类型是最常使用的一种整数类型。
对于大型程序常会遇到很大的整数,当超出 int 类型所表示的范围时就要使用 long 类型。
应用示例:
创建一个 Java 程序,在 main() 方法中声明各种整型的变量并赋予初值,最后将变量相加并输出结果,代码如下:
public static void main(String args[]) {//主函数
//整数
byte b = 100;//声明一个byte类型的变量并赋初值
System.out.println(b);
short s = 10000;//声明一个short类型的变量并赋初值
System.out.println(s);
int i = 1600000000;//声明一个int类型的变量并赋初值
System.out.println(i);
long l = 6000000000L;//声明一个long类型的变量并赋初值
System.out.println(l);
}
2.浮点型:
类型 关键字 内存 取值范围
单精度浮点型 float 4 字节 +/-3.4E+38F(6~7 个有效位)
双精度浮点型 double 8 字节 +/-1.8E+308 (15 个有效位)
Java 默认的浮点型为 double,例如,11.11 和 1.2345 都是 double 型数值。如果要说明一个 float 类型数值,就需要在其后追加字母 f 或 F,如 11.11f 和 1.2345F 都是 float 类型的常数。
可以使用如下方式声明 float 类型的变量并赋予初值。
float price = 12.2f; // 定义float类型并赋予初值
也可以使用如下的任意一种方式声明 double 类型的变量并赋予初值。
double price = 12.254d; // 定义double类型的变量并赋予初值
或
double price = 12.254; // 定义double类型的变量并赋予初值
注意:一个值要能被真正看作 float,它必须以 f(或 F)后缓结束;否则,会被当作 double 值。对 double 值来说,d(或 D)后缓是可选的。
代码示例:
//小数
double d = 3.14;
System.out.println(d);
float f = 2.6f;
System.out.println(f);
//小数是一个不精确的数
System.out.println(f-2);//0.5999999
3.字符型:
类型 关键字 内存 取值范围
字符型 char 2 字节 单一字符集
Java 语言中的字符类型(char)使用两个字节的 Unicode 编码表示,它支持世界上所有语言,可以使用单引号字符或者整数对 char 型赋值。
一般计算机语言使用 ASCII 编码,用一个字节表示一个字符。ASCII 码是 Unicode 码的一个子集,用 Unicode 表示 ASCII 码时,其高字节为 0,它是其前 255 个字符。
Unicode 字符通常用十六进制表示。例如“\u0000”~“\u00ff”表示 ASCII 码集。“\u”表示转义字符,它用来表示其后 4 个十六进制数字是 Unicode 码。
字符型变量的类型为 char,用来表示单个的字符,例如:
char letter = ‘D’;
char numChar = ‘5’;
第一条语句将字符 D 赋给字符型变量 letter;第二条语句将数字字符 5 赋给字符型变量 numChar。
示例代码:
下面代码在 main() 方法中定义两个字符类型的变量,并使之相对应的 ASCII(Unicode)值相加,最后将相加后的结果输出。
public static void main(String[] args) {
char a = ‘A’; // 向 char 类型的 a 变量赋值为 A,所对应的 ASCII 值为 65
char b = ‘B’; // 向 char 类型的 b 变量赋值为 B,所对应的 ASCII 值为 66
System.out.println(“A 的 ASCII 值与 B 的 ASCII 值相加结果为:”+(a+b));
}
保存该段代码并运行,输出结果如图所示。
该程序中,a 变量首先被赋值为“A”,字母 A 在 ASCII(和 Unicode)中对应的值为 65。接着又定义了一个类型为 char 的变量 b,赋值为“B”,字母 B 在 ASCII(和 Unicode)中所对应的值为 66。因此相加后得出的结果为 131。
提示:字符通常用 16 进制表示,范围从“\uOOOO”~“\uFFFF”,即从 0~65535。\uOOOO 和 \uFFFF 中的 u 告诉编译器是用两个字节(16 位)字符信息表示一个 Unicode 字符。
4.布尔型:
类型 关键字 内存 取值范围
布尔型 boolean 1 字节 true|false
布尔类型(boolean)用于对两个数值通过逻辑运算,判断结果是“真”还是“假”。Java 中用保留字 true 和 false 来代表逻辑运算中的“真”和“假”。因此,一个 boolean 类型的变量或表达式只能是取 true 和 false 这两个值中的一个。
在 Java 语言中,布尔类型的值不能转换成任何数据类型,true 常量不等于 1,而 false 常量也不等于 0。这两个值只能赋给声明为 boolean 类型的变量,或者用于布尔运算表达式中。
例如,可以使用以下语句声明 boolean 类型的变量。
boolean isable; // 声明 boolean 类型的变量 isable
boolean b = false; // 声明 boolean 类型的变量 b,并赋予初值为 false
注意:
所有的基本数据类型的大小(所占用的字节数)都已明确规定,在各种不同的平台上保持不变,这一特性有助于提高 Java 程序的可移植性。
Java 是一种强类型的语言,所有的变量都必须先明确定义其数据类型,然后才能使用。Java 中所有的变量、表达式和值都必须有自己的类型,没有“无类型”变量这样的概念。
2.3.1 引用数据类型
引用数据类型建立在基本数据类型的基础上,包括数组、类和接口。引用数据类型是由用户自定义,用来限制其他数据的类型。另外,Java 语言中不支持 C++ 中的指针类型、结构类型、联合类型和枚举类型。
引用类型还有一种特殊的 null 类型。所谓引用数据类型就是对一个对象的引用,对象包括实例和数组两种。实际上,引用类型变量就是一个指针,只是 Java 语言里不再使用指针这个说法。
空类型(null type)就是 null 值的类型,这种类型没有名称。因为 null 类型没有名称,所以不可能声明一个 null 类型的变量或者转换到 null 类型。
空引用(null)是 null 类型变量唯一的值。空引用(null)可以转换为任何引用类型。
在实际开发中,程序员可以忽略 null 类型,假定 null 只是引用类型的一个特殊直接量。
注意:空引用(null)只能被转换成引用类型,不能转换成基本类型,因此不要把一个 null 值赋给基本数据类型的变量
2.3.2 数据类型之间的转换
数字类型可以有数据类型上的转换,即将一种类型的值赋值给另外一种类型的变量。但要依据数据范围,符合一定规则。
-
隐式转换(自动类型转换)
将一种类型的数据赋给另外一种类型变量的时,符合如下两种条件,将会执行自动类型转换(automatic type conversion)。
a.两种数据类型彼此兼容
b.目标类型的取值范围大于原始数据类型(低级类型数据转换成高级类型数据)
当以上 2 个条件都满足时,隐式转换发生。例如 byte 类型向 short 类型转换时,由于 short 类型的取值范围较大,会自动将 byte 转换为 short 类型。
在运算过程中,由于不同的数据类型会转换成同一种数据类型,所以整型、浮点型以及字符型都可以参与混合运算。自动转换的规则是从低级类型数据转换成高级类型数据。转换规则如下:
数值型数据的转换:byte→short→int→long→float→double。
字符型转换为整型:char→int。
以上数据类型的转换遵循从左到右的转换顺序,最终转换成表达式中表示范围最大的变量的数据类型。
示例代码:
顾客到超市购物,购买牙膏 2 盒,面巾纸 4 盒。其中牙膏的价格是 10.9 元,面巾纸的价格是 5.8 元,求商品总价格。实现代码如下:
public static void main(String[] args) {
float price1 = 10.9f; // 定义牙膏的价格
double price2 = 5.8; // 定义面巾纸的价格
int num1 = 2; // 定义牙膏的数量
int num2 = 4; // 定义面巾纸的数量
double res = price1 * num1 + price2 * num2; // 计算总价
System.out.println(“一共付给收银员” + res + “元”); // 输出总价
}
上述代码中首先定义了一个 float 类型的变量存储牙膏的价格,然后定义了一个 double 类型的变量存储面巾纸的价格,再定义两个 int 类型的变量存储物品的数量,最后进行了乘运算以及和运算之后,将结果储存在一个 double 类型的变量中进行输出。
程序执行结果如下图 1 所示:
从执行结果看出,float、int 和 double 三种数据类型参与运算,最后输出的结果为 double 类型的数据。这种转换一般称为“表达式中类型的自动提升”。
自动类型提升有好处,但它也会引起令人疑惑的编译错误。例如,下面看起来正确的程序却会引起问题:
byte b = 50;
b = b * 2; // Type mismatch: cannot convert from int to byte
如上所示,第二行会报“类型不匹配:无法从int转换为byte”错误。
该程序试图将一个完全合法的 byte 型的值 502 再存储给一个 byte 型的变量。但是当表达式求值的时候,操作数被自动的提升为 int 型,计算结果也被提升为 int 型。这样表达式的结果现在是 int 型,不强制转换它就不能被赋为 byte 型。确实如此,在这个特别的情况下,被赋的值将仍然适合目标类型。
所以应该使用一个显示的强制类型转换,例如:
byte b = 50;
b = (byte)(b2);
这样就能产生正确的值 100。
注意:char 类型比较特殊,char 自动转换成 int、long、float 和 double,但 byte 和 short 不能自动转换为 char,而且 char 也不能自动转换为 byte 或 short。
2.显式转换(强制类型转换)
范围大的数据类型值(如double),不可以自动转换为范围小的数据类型值(如int),但是可以强制转换。所以当两种数据类型不兼容,或目标类型的取值范围小于源类型时,自动转换将无法进行,这时就需要进行强制类型转换。其语法格式如下:
范围小的数据类型 变量 = (范围小的数据类型) 范围大的数据类型值
强制转换的实例如下:
int i = (int)6.718; //i的值为6
double b = 5.0;
a = (int)b;
上述代码中首先将 double 类型变量 b 的值强制转换成 int 类型,然后将值赋给 a,但是变量 b 本身的值是没有发生变化的。
在强制类型转换中,如果是将浮点类型的值转换为整数,直接去掉小数点后边的所有数字;而如果是整数类型强制转换为浮点类型时,将在小数点后面补零。
代码示例:
顾客到超市购物,购买牙膏 2 盒,面巾纸 4 盒。其中牙膏的价格是 10.9 元,面巾纸的价格是 5.8 元,求商品总价格,在计算总价时采用 int 类型的数据进行存储。实现代码如下:
public static void main(String[] args) {
float price1 = 10.9f;
double price2 = 5.8;
int num1 = 2;
int num2 = 4;
int res2 = (int) (price1 * num1 + price2 * num2);
System.out.println(“一共付给收银员” + res2 + “元”);
}
在上述实例中,有 double 类型、float 类型和 int 类型的数据参与运算,其运算结果默认为 double 类型,题目要求的结果为 int 类型,因为 int 类型的取值范围要小于 double 类型的取值范围,所以需要进行强制类型转换。
程序执行结果如下图所示:
2.4 运算符
运算符用于执行程序代码运算,会针对一个以上操作数项目来进行运算。例如:2+3,其操作数是2和3,而运算符则是“+”。运算符大致可以分为5种类型:算术运算符、条件运算符、关系运算符、赋值运算符和逻辑运算符。
2.4.1 算数运算符
Java 中的算术运算符主要用来组织数值类型数据的算术运算,按照参加运算的操作数的不同可以分为一元运算符和二元运算符。
一元运算符
算术一元运算一共有 3 个,分别是 -、++ 和 --。具体说明参见表 1。
运 算 符 名 称 说 明 例 子
-
取反符号 取反运算 b=-a
++ 自加一 先取值再加一,或先加一再取值 a++ 或 ++a
– 自减一 先取值再减一,或先减一再取值 a-- 或 --a自增(++):将变量的值加1,分前缀式(如++i)和后缀式(如i++)。前缀式是先加1再使用;后缀式是先使用再加1。
自减(–):将变量的值减1,分前缀式(如–i)和后缀式(如i–)。前缀式是先减1再使用;后缀式是先使用再减1。
int a = 12;
System.out.println(-a);
int b = a++;
System.out.println(b);
b = ++a;
System.out.println(b);
上述代码第 2 行是 -a,是把 a 变量取反,结果输出是 -12。第 4 行代码是先把 a 赋值给 b 变量再加一,即先赋值后 ++,因此输出结果是 12。第 6 行代码是把 a 加一,然后把 a 赋值给 b 变量,即先 ++ 后赋值,因此输出结果是 14。
输出结果如下图所示:
二元运算符
Java 中算术运算符的功能是进行算术运算,除了经常使用的加(+)、减(-)、乘(*)和除(\)外,还有取模运算(%)。具体说明参见表。
运 算 符 名 称 说 明 例 子
- 加 求 a 加 b 的和,还可用于 String 类型,进行字符串连接操作 a + b
- 减 求 a 减 b 的差 a - b
- 乘 求 a 乘以 b 的积 a * b
/ 除 求 a 除以 b 的商 a / b
% 取余 求 a 除以 b 的余数 a % b
算术运算符都是双目运算符,即连接两个操作数的运算符。优先级上,*、/、% 具有相同运算级别,并高于 +、-(+、- 具有相同级别)。例如:
int a = 4, b = 2, c = 3;
int d = a * (b + c) % c;
表达式中的运算规则与数学运算中的规则是相同的。首先计算括号内的值,其次按从左向右的结合方向计算乘法,最后做求余运算,表达式的结果为 2, 然后把 2 赋值给 d。
例如:
① int x=2,y=1; 表达式 y/x 的结果是 0。
② float x=2.0f; int y=1; 表达式 y/x 的结果是 0.5。
在 ① 中整型变量 x 和 y 相除,其结果仍为整型数据 0;在 ② 中由于两个不同类型的数据进行运算,此时首先要进行类型转换,会把 int 型的 y 转换成与 x 一样的 float 型,然后相除,最终结果为 float 类型的数字 0.5。
【例】编写一个程序,输出不同类型的两个数,执行相加、相减、相乘、相除和求余后输入结果。
实现代码如下:
public static void main(String[] args) {
float f1 = 9 % 4;// 保存取余后浮点类型的结果
double da = 9 + 4.5; // 双精度加法
double db = 9 - 3.0; // 双精度减法
double dc = 9 * 2.5; // 双精度乘法
double dd = 9 / 3.0; // 双精度除法
double de = 9 % 4; // 双精度取余
System.out.println("整数的算术运算"); // 整数的加、减、乘、除和取余
System.out.printf("9+4=%d \n", 9 + 4);
System.out.printf("9-4=%d \n", 9 - 4);
System.out.printf("9*4=%d \n", 9 * 4);
System.out.printf("9/4=%d \n", 9 / 4);
System.out.printf("9%%4=%d \n", 9 % 4);
System.out.println("\n浮点数的算术运算"); // 浮点数的加、减、乘、除和取余
System.out.printf("9+4.5f=%f \n", 9 + 4.5f);
System.out.printf("9-3.0f=%f \n", 9 - 3.0f);
System.out.printf("9*2.5f=%f \n", 9 * 2.5f);
System.out.printf("9/3.0f=%f \n", 9 / 3.0f);
System.out.printf("9%%4=%f \n", f1);
System.out.println("\n双精度数的算术运算"); // 双精度数的加、减、乘、除和取余
System.out.printf("9+4.5=%4.16f \n", da);
System.out.printf("9-3.0=%4.16f \n", db);
System.out.printf("9*2.5=%4.16f \n", dc);
System.out.printf("9/3.0=%4.16f \n", dd);
System.out.printf("9%%4=%4.16f \n", de);
System.out.println("\n字符的算术运算"); // 对字符的加法和减法
System.out.printf("'A'+32=%d \n", 'A' + 32);
System.out.printf("'A'+32=%c \n", 'A' + 32);
System.out.printf("'a'-'B'=%d \n", 'a' - 'B');
}
保存文件并运行,输出的结果如下所示。
整数的算术运算
9+4=13
9-4=5
9*4=36
9/4=2
9%4=1
浮点数的算术运算
9+4.5f=13.500000
9-3.0f=6.000000
9*2.5f=22.500000
9/3.0f=3.000000
9%4=1.000000
双精度数的算术运算
9+4.5=13.5000000000000000
9-3.0=6.0000000000000000
9*2.5=22.5000000000000000
9/3.0=3.0000000000000000
9%4=1.0000000000000000
字符的算术运算
‘A’+32=97
‘A’+32=a
‘a’-‘B’=31
本示例中使用了 4 种类型来执行算术运算。其中,整数类型的结果最容易理解,浮点型和双精度型返回的结果都带有小数,字符型将会把字符转换为 ASCII 码再运算。
从输出结果中可以看到,整数之间的运算结果只保留整数部分,浮点型运算时保留 6 位小数部分,双精度运算时则保留 16 位小数部分。
注意:Java 语言算术运算符的优先级是先乘除后加减。例如在表达式“a-bc”中,b 的左侧为减号,右侧为乘号,而乘号优先级高于减号,因此该表达式可以转换为“a-(bc)”。
如果在一个表达式中的多个算术运算符的优先级别相同,例如“a-b+c”,此时将按照运算符的结合方向决定顺序。算术运算符的结合方向都是“从左至右”,即先左后右。因此 b 先与减号结合,执行“a-b”的运算,再执行加 c 的运算。
算术赋值运算符
算术赋值运算符只是一种简写,一般用于变量自身的变化,具体说明参见表 。
运 算 符 名 称 范例
+= 加赋值 a += b、a += b+3
-= 减赋值 a -= b
*= 乘赋值 a *= b
/= 除赋值 a /= b
%= 取余赋值 a %= b
示例代码如下:
int a = 1;
int b = 2;
a += b; // 相当于 a = a + b
System.out.println(a);
a += b + 3; // 相当于 a = a + b + 3
System.out.println(a);
a -= b; // 相当于 a = a - b
System.out.println(a);
a = b; // 相当于 a=ab
System.out.println(a);
a /= b; // 相当于 a=a/b
System.out.println(a);
a %= b; // 相当于 a=a%b
System.out.println(a);
运行结果如下图所示:
上述例子分别对整型进行了+=、-=、*=、/= 和 %= 运算,具体语句不再赘述
2.4.2 赋值运算符
赋值运算符是指为变量或常量指定数值的符号。赋值运算符的符号为“=”,它是双目运算符,左边的操作数必须是变量,不能是常量或表达式。
其语法格式如下所示:
变量名称=表达式内容
在 Java 语言中,“变量名称”和“表达式”内容的类型必须匹配,如果类型不匹配则需要自动转化为对应的类型。
赋值运算符的优先级低于算术运算符,结合方向是自右向左;不是数学中的等号,它表示一个动作,即将其右侧的值送到左侧的变量中(左侧只允许是变量,不能是表达式或其他形式);不要将赋值运算符与相等运算符“==”混淆。
赋值运算符与其他运算符一起使用,可以表达多种赋值运算的变异效果。例如,在基本的赋值运算符的基础之上,可以结合算术运算符,以及后面要学习的位运算符,组合成复合的赋值运算符。赋值运算符和算数运算符组成的复合赋值运算的含义及其使用实例如表所示。
运算符 含义 范例 结果
= 赋值 int a=2 2
+= 加后赋值 int a=2,a+=2 4
-= 减后赋值 int a=2,a-=2 0
= 乘后赋值 int a=2,a=2 4
/= 整除后赋值 int a=2,a/=2 1
注意:
诸如+=这样形式的赋值运算符,会将结果自动强转成等号左边的数据类型。
赋值运算符的示例。
int x, y, z; // 定义3个整型的变量
x = y = z = 5; // 为变量赋初值为5
x += 10; // 等价于x=x+10,结果x=15
y -= 3; // 等价于y=y-3,结果y=2
z = 5; // 等价于z=z5,结果z=25
x /= 4; // 等价于x=x/4,结果x=3
z %= x; // 等价于z=z%x,结果z=1
例如,一件商品的单价从 10.25 元降了 1.25 元,而自己购买的数量由原来的两个增加到 10 个,可以使用复合赋值运算符来计算购买商品的总价。
实现代码如下:
public static void main(String[] args) {
double price = 10.25; // 定义商品的单价,赋值为10.25
double total = 0; // 定义总价初始为0
int count = 2; // 定义购买数量,赋值为2
price -= 1.25; // 减去降价得到当前单价
count = 5; // 现在需要购买10个,即原来数量的5倍
total = price * count; // 总价=当前单价数量
System.out.printf(“商品当前的单价为:%4.2f \n”, price); // 输出当前单价
System.out.printf(“购买商品的数量为:%d \n”, count); // 输出购买数量
System.out.printf(“总价为:%4.2f \n”, total); // 输出总价
}
保存代码并运行,输出的结果如下:
注意:虽然 Java 支持这种一次为多个变量赋值的写法,但这种写导致程序的可读性降低,因此不推荐这样写。
在该程序中,表示商品单价的 price 变量值为 10.25,而现在降了 1.25,在原来的基础上减去 1.25 即可获取现在的单价。而原来购买的数量为两个,现在需要购买 10 个,可以使用“count*=5”将数量乘以 5 倍之后的值赋值给 count 本身。
赋值运算符还用于将表达式的值赋给变量,如下代码是正确的。
double d1 = 12.34
double d2 = d1 + 5; // 将表达式的值赋给d2
System.out.println(d2); // 输出 d2 的值,将输出 17.34
赋值运算符还可与其他运算符结合,扩展成功能更加强大的赋值运算符
2.4.3 逻辑运算符
逻辑运算符用于计算两个布尔值经过指定逻辑后的运算结果,结果同样是一个布尔值,具体如表所示。
运算符 含义 范例 结果
& 与(并且) false&true False
| 或 false|true True
^ 异或 true^flase True
! 非(取反) !true Flase
&& 短路与 false&&true False
|| 短路或 true ||true True
&& 与 & 区别:如果 a 为 false,则不计算 b(因为不论 b 为何值,结果都为 false)
|| 与 | 区别:如果 a 为 true,则不计算 b(因为不论 b 为何值,结果都为 true)
注意:短路与(&&)和短路或(||)能够采用最优化的计算方式,从而提高效率。在实际编程时,应该优先考虑使用短路与和短路或。
结果为 boolean 型的变量或表达式可以通过逻辑运算符结合成为逻辑表达式。逻辑运算符 &&、|| 和 !按表 2 进行逻辑运算。
a b a&&b a||b !a
true true true true false
false true false true true
true false false true false
false false false false true
逻辑运算符的优先级为:!运算级别最高,&& 运算高于 || 运算。!运算符的优先级高于算术运算符,而 && 和 || 运算则低于关系运算符。结合方向是:逻辑非(单目运算符)具有右结合性,逻辑与和逻辑或(双目运算符)具有左结合性。
下面是一些使用逻辑运算符的示例。
x>0 && x<=100 // 第一行语句
y%40 || y%30 // 第二行语句
!(x>y) // 第三行语句
其中,第一行语句用于判断 x 的值是否大于 0 且小于或等于 100,只有两个条件同时成立结果才为真(true)。第二行语句用于判断 y 的值是否能被 4 或者 3 整除,只要有一个条件成立,结果就为真(true)。第三行语句先比较 x 和 y,再将比较结果取反,即如果 x 大于 y 成立,则结果为假(false),否则为真(true)。
2.4.4 关系运算符
即判断两个操作数的大小关系及是否相等关系,比较运算符的返回一定为布尔值。
运算符 含义 实例 结果 == 相等于 4==3 false
!= 不等于 4!=3 true
< 小于 4<3 false
大于 4>3 true
<= 小于等于 4<=3 false
= 大于等于 4>=3 true
注意:
1.基本类型的变量、值不能和引用类型的变量、值使用 == 进行比较;
2.boolean 类型的变量、值不能与其他任意类型的变量、值使用 == 进行比较;
3.如果两个引用类型之间没有父子继承关系,那么它们的变量也不能使用 == 进行比较。
4.== 和 != 可以应用于基本数据类型和引用类型。当用于引用类型比较时,比较的是两个引用是否指向同一个对象,但当时实际开发过程多数情况下,只是比较对象的内容是否相当,不需要比较是否为同一个对象。
关系运算符的优先级为:>、<、>=、<= 具有相同的优先级,并且高于具有相同优先级的 !=、。关系运算符的优先级高于赋值运算符而低于算术运算符,结合方向是自左向右。
关系表达式通常用于 Java 程序的逻辑判断语句的条件表达式中。使用关系表达式要注意以下几点:
运算符 >=、、!=、<= 是两个字符构成的一个运算符,用空格从中分开写就会产生语法错误。例如 x> =y; 是错误的,但是可以写成x >= y; 在运算符的两侧增加空格会提高可读性。同样将运算符写反,例如 =>、=<、=! 等形式会产生语法错误。
由于计算机内存放的实数与实际的实数存在着一定的误差,如果对浮点数进行 (相等)或 !=(不相等)的比较,容易产生错误结果,应该尽量避免。
不要将“”写成“=”。
下面是一些使用关系运算符的示例。
a > b // 比较变量a的值是否大于变量b的值
x+y> = z // 比较变量x与变量y的和是否大于或等于变量z的值
width * width+size != area // 比较变量width的平方加上变量size的值是否与变量area的值不相等
name == “zhht” // 比较变量name的值是否等于字符串nzht
pass != “123456” // 比较变量pass的值是否不等于字符串“123456”
示例:
编写一个程序,使用户可以从键盘输入两个数,并判断这两个数之间的大小。 实现代码如下:
public static void main(String[] args) {
int number1, number2; // 定义变量,保存输入的两个数
System.out.print(“请输入第一个整数(number1):”);
Scanner input = new Scanner(System.in);
number1 = input.nextInt(); // 输入第一个数
System.out.print(“请输入第二个整数(number2):”);
input = new Scanner(System.in);
number2 = input.nextInt(); // 输入第二个数
System.out.printf(“number1=%d,number2=%d\n”, number1, number2); // 输出这两个数
// 判断用户输入的两个数是否相等
if (number1 == number2) {
System.out.println(“number1 和 number2 相等。”);
}
// 判断用户输入的两个数据是否相等
if (number1 != number2) {
System.out.println(“number1 和 number2 不相等。”);
// 判断用户输入的数1是否大于数2
if (number1 > number2) {
System.out.println(“number1 大于 number2。”);
}
// 判断用户输入的数1是否小于数2
if (number1 < number2) {
System.out.println(“number1 小于 number2。”);
}
}
}
保存程序并运行,运行结果如下所示:
本程序中,使用 input.nextInt() 接收用户从键盘输入的两个数,然后通过关系运算符来比较这两个数之间的大小。这里用到了 if 语句,它是一个流程控制语句,将在后面的章节中详细讲解。
2.4.5 位运算符
Java 定义的位运算(bitwise operators)直接对整数类型的位进行操作,这些整数类型包括 long,int,short,char 和 byte。
位运算符主要用来对操作数二进制的位进行运算。按位运算表示按每个二进制位(bit)进行计算,其操作数和运算结果都是整型值。
Java 语言中的位运算符分为位逻辑运算符和位移运算符两类,下面详细介绍每类包含的运算符。
位逻辑运算符
位逻辑运算符包含 4 个:&(与)、|(或)、~(非)和 ^(异或)。除了 ~(即位取反)为单目运算符外,其余都为双目运算符。表 1 中列出了它们的基本用法。
运算符 含义 实例 结果
& 按位进行与运算(AND) 4 & 5 4
| 按位进行或运算(OR) 4 | 5 5
^ 按位进行异或运算(XOR) 4 ^ 5 1
~ 按位进行取反运算(NOT) ~ 4 -5
位与运算符
位与运算符为&,其运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位同时为 1,那么计算结果才为 1,否则为 0。因此,任何数与 0 进行按位与运算,其结果都为 0。
例如下面的表达式:
100&0
图 1 所示为这个运算过程,结果为 0。
图 1 100位与0的运算过程
下面是两个非零的数字进行位与运算的过程。
int x = 5,y = 12; // 创建整型变量保存两个数
int z = x&y; // 对这两个数进行位与运算,结果保存到z
这两行语句执行后变量 Z 的值是 4,图 2 所示为这个运算过程。
图 2 5位与12的运算过程
位或运算符
位或运算符为|,其运算规则是:参与运算的数字,低位对齐,高位不足的补零。如果对应的二进制位只要有一个为 1,那么结果就为 1;如果对应的二进制位都为 0,结果才为 0。
下面是一个使用位或运算符的表达式。
11|7
运算结果为 15,图 3 所示为其运算过程。
图 3 11位或7的运算过程
位异或运算符
位异或运算符为^,其运算规则是:参与运算的数字,低位对齐,高位不足的补零,如果对应的二进制位相同(同时为 0 或同时为 1)时,结果为 0;如果对应的二进制位不相同,结果则为 1。
下面是一个使用位异或运算符的表达式。
11^7
运算结果为 12,图 4 所示为其运算过程。
图 4 11位异或7的运算过程
提示:在有的高级语言中,将运算符^作为求幂运算符,要注意区分。
位取反运算符
位取反运算符为~,其运算规则是:只对一个操作数进行运算,将操作数二进制中的 1 改为 0,0 改为 1。
下面是一个使用位取反运算符的表达式。
~10
运算结果为 65525,图 5 所示为其运算过程。
图 5 对10位取反的运算过程
我们可以使用如下的程序来检查这个运算结果。
int i = 10;
System.out.printf(“%d \n”,~i);
编译执行以上程序,会发现输出的结果是 -11,而不是 65525。这是因为取反之后的结果是十六进制数,而在上面的程序中使用 %d 将输出转换为了十进制数。
可以使用如下语句查看十六进制结果。
int i=10;
System.out.printf(“%x \n”,~i);
可以看到输出结果为 fff5,将它转换为二进制是 1111111111110101。这个二进制数的最高位为 1,表示这个数为负数。除最高位外,按位取反再加 1,即得到二进制原码 1000000000001011,用十进制数表示即为 -11。
注意:位运算符的操作数只能是整型或者字符型数据以及它们的变体,不用于 float、double 或者 long 等复杂的数据类型。
位移运算符
位移运算符用来将操作数向某个方向(向左或者右)移动指定的二进制位数。表列出了 Java 语言中的两个位移运算符,它们都属于双目运算符。
运算符 含义 实例 结果
» 右移位运算符 8»1 4
« 左移位运算符 9«2 36
左位移运算符
左移位运算符为«,其运算规则是:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
例如,将整数 11 向左位移 1 位的过程如图 6 所示。
图 6 对11左移1位运算过程
图 6 中可以看到,原来数的所有二进制位都向左移动 1 位。原来位于左边的最高位 0 被移出舍弃,再向尾部追加 0 补位。最终到的结果是 22,相当于原来数的 2 倍。
右位移运算符
右位移运算符为»,其运算规则是:按二进制形式把所有的数字向右移动对应的位数,低位移出(舍弃),高位的空位补零。
例如,将整数 11 向右位移 1 位的过程如图 7 所示。
图 7 对11右移1位运算过程
图 7 中可以看到,原来数的所有二进制位都向右移动 1 位。原来位于右边的最低位 1 被移出舍弃,再向最高位追加 0 补位。最终到的结果是 5,相当于原数整除 2 的结果。
复合位赋值运算符
所有的二进制位运算符都有一种将赋值与位运算组合在一起的简写形式。复合位赋值运算符由赋值运算符与位逻辑运算符和位移运算符组合而成。表 3 列出了组合后的复合位赋值运算符。
运算符 含义 实例 结果
&= 按位与赋值 num1 &= num2 等价于 num 1=num 1 & num2
|= 按位或赋值 num1 |= num2 等价于 num 1=num 1 | num2
^= 按位异或赋值 num1 ^= num2 等价于 num 1=num 1 ^ num2
-= 按位取反赋值 num1 -= num2 等价于 num 1=num 1 - num2
«= 按位左移赋值 num1 «= num2 等价于 num 1=num 1 « num2
»= 按位右移赋值 num1 »= num2 等价于 num 1=num 1 » num2
下面的程序定义了几个 int 型变量,然后运用位赋值简写的形式将运算后的值赋给相应的变量:
纯文本复制
int a = 1;
int b = 2;
int c = 3;
a &= 4;
a |= 4;
a ^= c;
a -= 6;
b >>= 1;
c <<= 1;
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
该程序的输出为:
a = 1
b = 1
c = 6
2.4.6 三目运算符
三元运算符(也叫三目运算符)经常用于取代某个类型的 if-else 语句。条件运算符的符号表示为“?:”,使用该运算符时需要有三个操作数,因此称其为三目运算符。使用条件运算符的一般语法结构为:
result = ? : ;
其中,expression 是一个布尔表达式。当 expression 为真时,执行 statement1, 否则就执行 statement2。此三元运算符要求返回一个结果,因此要实现简单的二分支程序,即可使用该条件运算符。
下面是一个使用条件运算符的示例。
int x,y,z;
x = 6,y = 2;
z = x>y ? x-y : x+y;
在这里要计算 z 的值,首先要判断 x>y 表达的值,如果为 true,z 的值为 x-y;否则 z 的值为 x+y。很明显 x>y 表达式结果为 true,所以 z 的值为 4。
技巧:可以将条件运算符理解为 if-else 语句的简化形式,在使用较为简单的表达式时,使用该运算符能够简化程序代码,使程序更加易读。
在使用条件运算符时,还应该注意优先级问题,例如下面的表达式:
x>y ? x-=y : x+=y;
在编译时会出现语法错误,因为条件运算符优先于赋值运算符,上面的语句实际等价于:
(x>y ? x-=y : x)+=y;
而运算符“+=”是赋值运算符,该运算符要求左操作数应该是一个变量,因此出现错误。为了避免这类错误,可以使用括号“0”来加以区分。例如,下面是正确的表达式。
(x>y) ? (x-=y): (x+=y);
示例
在程序中声明 3 个变量 x、y、z,并由用户从键盘输入 x 的值,然后使用条件运算符向变量 y 和变量 z 赋值。 实现代码如下:
public class Test9 {
public static void main(String[] args) {
int x, y, z; // 声明三个变量
System.out.print(“请输入一个数:”);
Scanner input = new Scanner(System.in);
x = input.nextInt(); // 由用户输入x的值
// 判断x的值是否大于5,如果是y=x,否则y=-x
y = x > 5 ? x : -x;
// 判断y的值是否大于x,如果是z=y,否则z=5
z = y > x ? y : 5;
System.out.printf(“x=%d \n”, x);
System.out.printf(“y=%d \n”, y);
System.out.printf(“z=%d \n”, z);
}
}
保存程序并运行,运行效果如图 1 和图 2 所示:
图 1 键盘输入58
图 2 键盘输入4
该程序中,首先输入 x 的值为 58,然后判断 x 的值是否大于 5,显然条件是成立,则 y 的值为 x,即 y=58。接着判断 y 的值是否大于 x,因为 y 的值和 x 的值都为 58,所以该条件是不成立的,则 z=5。再次输入 x 的值为 4,然后判断 x 的值是否大于 5,不成立,则 y=-4;接着判断 y 的值是否大于 x,不成立,则 z=5
2.4.7 运算符的优先级
运算符的优先级,是指在表达式中哪一个运算符先计算,哪一个运算符后计算,与数学运算中认为的“先乘除,后加减,默认从左向右运算”是一个道理。
只有单目运算符、赋值运算符和三目运算符例外,其中,单目运算符、赋值运算符和三目运算符是从右向左结合的,也就是从右向左运算。
一般而言,单目运算符优先级较高,赋值运算符优先级较低。算术运算符优先级较高,关系和逻辑运算符优先级较低。多数运算符具有左结合性,单目运算符、三目运算符、赋值运算符具有右结合性。
下表列出了所有的运算符的优先级以及结合性。
优先级 运算符 结合性
1 ()、[]、{} 从左向右
2 !、+、-、~、++、-- 从右向左
3 、/、% 从左向右
4 +、- 从左向右
5 «、»、>>> 从左向右
6 <、<=、>、>=、instanceof 从左向右
7 ==、!= 从左向右
8 & 从左向右
9 ^ 从左向右
10 | 从左向右
11 && 从左向右
12 || 从左向右
13 ?: 从右向左
14 =、+=、-=、=、/=、&=、|=、^=、~=、«=、»=、>>>= 从右向左
使用优先级为 1 的小括号可以改变其他运算符的优先级,即如果需要将具有较低优先级的运算符先运算,则可以使用小括号将该运算符和操作符括起来。例如下面的表达式:
(x-y)z/5
在这个表达式中先进行括号内的减法运算,再将结果与 z 相乘,最后将积除以 5 得出结果。整个表达式的顺序按照从左向右执行,比较容易理解。
再来看一个复杂的表达式,如下所示。
–y || ++x && ++z;
这个表达式中包含了算术运算符和逻辑运算符。根据表 1 中列出的优先级,可以确定它的执行顺序如下:
① 先计算 y 的自减运算符,即 --y。
② 再计算 x 的自增运算符,即 ++x。
③ 接着计算 z 的自增运算符,即 ++z。
④ 由于逻辑与比逻辑或的优先级高,这里将 ② 和 ③ 的结果进行逻辑与运算,即 ++x && ++z。
⑤ 最后将 ④ 的结果与 ① 进行逻辑或运算,即 --y||++x&&++z。
如果没有上述对该表达式执行顺序的说明,第一眼看到它时将很难识别优先级。对于这类问题,可以通过添加小括号使表达的顺序更加清晰,而不用去查优先级表。如下所示为改进后的表达式。
(–y)||((++x)&&(++z));
技巧:记住这么多运算符的优先级是比较困难的,因此读者应该在实际应用中多多练习。
因为 Java 运算符存在这种优先级的关系,因此在做 SCJP 的时候或者某些公司的面试题,有如下 Java 代码:
int a = 5;
int b = 4;
int c = a+± --b++a/b-- >>2%a–;
问 c 的值是多少?这样的语句实在太恐怖了,即使多年的老程序员看到这样的语句也会眩晕。这样的代码只能在考试中出现,作为一个程序员如果写这样的代码,恐怕他马上就得走人了,因为他完全不懂程序开发。
源代码就是一份文档,源代码的可读性比代码运行效率更重要。 因此在这里要提醒大家:
不要把一个表达式写得过于复杂,如果一个表达式过于复杂,则把它分成几步来完成。
不要过多地依赖运算符的优先级来控制表达式的执行顺序,这样可读性太差,尽量使用()来控制表达式的执行顺序。
2.5 本章小结
本章总结
变量是一个数据存储空间的表示,它是存储数据的基本单元。
Java中常用的数据类型有整型(int)、双精度浮点型(double)、字符型(char)、
和字符串型(String)。
变量要先声明并赋值,然后才能使用。
Java数据类型转换是为了方便不同类型的数据之间进行运算。
数据类型转换包括自动类型和强制类型转换,发生自动类型转换时必须符合一定的条件。
Java提供了各种运算符,比如算术运算符、关系运算符、逻辑运算符等。
本章作业
一、数据类型
1、整型常量( A )
A、12 B、12. C、 .23 D、34.4
2、浮点型常量( C )
A、12 B、null C、 .23 D、false
3、符号常量的修饰符( C )
A、float B、int C、final D、main
4、转义字符里单引号用什么表示( D )
A、// B 、/ C 、\ D 、 \’
5、转义字符里回车用什么表示( A )
A、\r B、\b C、/r D、/b
6、布尔类型里有2个类型,分别是true和( B )
A、true B、false C、int D、short
7、下面不是常量值的是( D )
A、0XAF0 B、null C、“null“ D、1_21
8、常量没有那个类型( B )
A、整型 B、质数型 C、浮点型 D、布尔型
二、变量
1、变量整数类型有byte、short、int和( A )
A、long B、float C、double D、char
2、变量浮点数类型有float和( c )
A、long B、int C、double D、char
3、变量字符类型有( D )
A、long B、float C、double D、char
4、变量的声明格式( B )
A、变量类型 变量名;
B、变量类型 变量名=初始化值;
C、变量名 变量类型=初始化值;
D、变量名 =初始化值;
5、下面变量声明正确的是( C )
A、int a b
B、int a=b=2;
C、int a=1,b=2;
D、int a=”abc”;
6、自动类型转换的顺序( C )
A、byte -> int -> short -> long -> float -> double
B、byte -> short -> int -> float -> long -> double
C、byte -> short -> int -> long -> float -> double
D、double -> short -> int -> long -> float -> byte
7、boolean型变量在内存当中的字节数为( A )
A、1 B、2 C、4 D、8
8、int型变量在内存当中的字节数为( C )
A、1 B、2 C、4 D、8
9、double型变量在内存当中的字节数为( D )
A、1 B、2 C、4 D、8
10、char型变量在内存当中的字节数为( B )
A、1 B、2 C、4 D、8
三、运算符
1、int a=1;int b=2;a=a+b;b=a-b;a=a*b;b=a/b;结果为( B )
A、a = -3 b = -1 B、a = 3 b = 3
C、a = 3 b = 1 D、a = -3 b = 3
2、b=a++的运算过程是( C )
A、b=a+1 B、a=a+1 C、b=a a=a+1 D、a=a+1 b=a
3、b=++a的运算过程是( D )
A、b=a+1 B、a=a+1 C、b=a a=a+1 D、a=a+1 b=a
4、int a=3;int b=3;a%b的结果为( A )
A、0 B、1 C、2 D、3
5、double a=7;double b=5;a/b的结果为( C )
A、0 B、1 C、1、4 D、2
6、int a=3;int b=4;a==b的结果为( A )
A、false B、true C、a=3 D、a=4
7、int x=12;int y=15;int max=x>y?x:y;的运算结果是( D )
A、true B、false C、max=12 D、max=15
8、boolean x=true; boolean y=false; boolean z;下列结果为true的是( D )
A、z=!x B、z=x&&y C、z=y D、z=x||y;
9、int a=7;int b=5;a+=b;的结果为( B )
A、a=7 b=5 B、a=12 b=5 C、a=7 b=12 D、a=5 b=7
10、int a=7,b=10;a += --b;的结果为( C )
A、a=7,b=10 B、a=17 b=9 C、a=16 b=9 D、a=16 b=10
第3章 流程控制语句
流程是人们生活中不可或缺的一部分,它表示人们每天都在按照一定的流程做事。比如出门搭车、上班、下班、搭车回家。这其中的步骤是有顺序的。程序设计也需要有流程控制语句来完成用户的要求,根据用户的输入决定程序要进入什么流程,即“做什么”以及“怎么做”等。
从结构化程序设计角度出发,程序有 3 种结构:顺序结构、选择结构和循环结构。若是在程序中没有给出特别的执行目标,系统则默认自上而下一行一行地执行该程序,这类程序的结构就称为顺序结构。
到目前为止,我们所编写的程序都属于顺序结构。但是事物的发展往往不会遵循早就设想好的轨迹进行,因此,所设计的程序还需要能够具有在不同的条件下处理不同问题以及当需要进行一些相同的重复操作时,如何能省时省力地解决问题的能力。
3.1 选择结构
选择结构也被称为分支结构。选择结构有特定的语法规则,代码要执行具体的逻辑运算进行判断,逻辑运算的结果有两个,所以产生选择,按照不同的选择执行不同的代码
3.1.1 if else 结构
if 结构
if 语句是使用最多的条件分支结构,它属于选择语句,也可以称为条件语句。
if 选择结构是根据条件判断之后再做处理的一种语法结构。默认情况下,if 语句控制着下方紧跟的一条语句的执行。不过,通过语句块,if 语句可以控制多个语句。
if 语句的最简语法格式如下,表示“如果满足某种条件,就进行某种处理”。
if (条件表达式) {
语句块;
}
其中“条件表达式”和“语句块”是比较重要的两个地方。
条件表达式:条件表达式可以是任意一种逻辑表达式,最后返回的结果必须是一个布尔值。取值可以是一个单纯的布尔变量或常量,也可以是使用关系或布尔运算符的表达式。如果条件为真,那么执行语句块;如果条件为假,则语句块将被绕过而不被执行。
语句块:该语句块可以是一条语句也可以是多条语句。如果仅有一条语句,可省略条件语句中的大括号 {}。当从编程规范角度不要省略大括号,省略大括号会使程序的可读性变差。
if 语句执行流程图:
示例:
编写一个 Java 程序,允许用户从键盘输入一个数字,再判断该数是否大于 100。使用 if 语句的实现代码如下:
public static void main(String[] args) {
System.out.println(“请输入一个数字:”);
Scanner input = new Scanner(System.in);
int num = input.nextInt(); // 接收键盘输入数据
// 判断用户输入的数据是否大于100
if (num > 100) {
System.out.println("输入的数字大于100");
}
// 判断用户输入的数据是否等于100
if (num == 100) {
System.out.println("输入的数字等于100");
}
// 判断用户输入的数据是否小于100
if (num < 100) {
System.out.println("输入的数字小于100");
}
}
运行该程序,分别使用键盘输入 99、100 和 105,结果如下所示:
请输入一个数字:
99
输入的数字小于100
请输入一个数字:
100
输入的数字等于100
请输入一个数字:
105
输入的数字大于100
示例:
假设有 num1 和 num2 两个变量,它们的值分别是 50 和 34。下面编写程序,要求使用 if 语句判断 num1 和 num2 的大小关系,并输出比较结果。
实现代码如下:
public static void main(String[] args) {
int num1 = 50;
int num2 = 34;
if (num1 > num2) {
System.out.println(“num1大于num2”);
}
if (num1 == num2) {
System.out.println("num2等于num2");
}
if (num1 < num2) {
System.out.println("num1小于num2");
}
}
该段选择语句判断了 num1 值和 num2 值的大于、等于和小于关系。此处 num1 为 50,num2 为 34,所以执行后会输出“num1 大于 num2”。
示例:
在上述两个案例代码中,由于每个 if 语句的语句块中只包含一条语句,所以省略了大括号。本实例在登录系统中要求用户名、密码和验证码都必须正确,否则将显示登录失败及错误提示。其中的语句块有多条语句,所以需要使用大括号。代码如下:
public static void main(String[] args) {
String username = “admin”; // 用户名
String userpass = “123456”; // 密码
String code = “0000”; // 验证码
if (username != “admin” && userpass != “123456” && code != “0000”) {
System.out.println(“登录失败!”);
System.out.println(“请检查输入的用户名、密码和验证码是否正确!”);
}
}
在这里为 if 语句设置了一个复杂的复合表达式来验证登录条件。执行后的输出结果如下:
登录失败!
请检查输入的用户名、密码和验证码是否正确!
if-else 结构
单 if 语句仅能在满足条件时使用,而无法执行任何其他操作(停止)。而结合 else 语句的 if 可以定义两个操作,此时的 if…else 语句表示“如果条件正确则执行一个操作,否则执行另一个操作”。
使用 if…else 语句的语法格式如下所示:
if (表达式) {
语句块1;
} else {
语句块2;
}
在上述语法格式中,如果 if 关键字后面的表达式成立,那么就执行语句块 1,否则的话则执行语句块 2。
互斥条件判断流程图:
示例:
public static void main(String[] args) {
int num1 = 50;
int num2 = 34;
// 如果num1等于num2
if (num1 == num2) {
System.out.println("num1等于num2");
}
// 如果num1大于num2
if (num1 > num2) {
System.out.println("num1大于num2");
} else {
// 否则就是num1小于num2
System.out.println("num1小于num2");
}
}
双条件语句减少了代码的编写量,同时增强了程序的可读性。简化后的结果还是一样,执行后会输出“num1 大于 num2”。
多条件 if-else-if 语句
在多个条件中选择满足条件的if语句体执行。
通常表现为“如果满足某种条件,就进行某种处理,否则如果满足另一种条件才执行另一种处理……,这些条件都不满足则执行最后一种条件”。
if…else if 多分支语句的语法格式如下所示:
if(表达式1) {
语句块1;
} else if(表达式2) {
语句块2;
…
} else if(表达式n) {
语句块n;
} else {
语句块n+1;
}
可以看出,else-if 结构实际上是 if-else 结构的多层嵌套。明显的特点就是在多个分支中只执行一个语句组,而其他分支都不执行,所以这种结构可以用于有多种判断结果的分支中。
在使用 if…else if 语句时,依次判断表达式的值,当某个分支的条件表达式的值为 true 时,则执行该分支对应的语句块,然后跳到整个 if 语句之外继续执行程序。如果所有的表达式均为 false,则执行语句块 n+1,然后继续执行后续程序,其运行流程如图所示。
示例:
同样以比较 num1 和 num2 的大小为例,使用 if…else if 多条件的实现代码如下:
public static void main(String[] args) {
int num1 = 50;
int num2 = 34;
if (num1 == num2) { // 如果num1等于num2
System.out.println("num1等于num2");
} else if (num1 > num2) { // 如果num1大于num2
System.out.println("num1大于num2");
} else { // 否则就是小于
System.out.println("num1小于num2");
}
}
如上述代码所示,num1 和 num2 不满足 if 语句的“num1==num2”条件,接着测试 else if 的“num1>num2”条件,满足该条件并输出“num1 大于 num2”。
示例:
假设某学校对成绩的判断标准是:不低于 90,可以评为优秀;低于 90 但不低于 80,可以评为良好;低于 80 但不低于 60,可以评为中等;否则评为差。
public static void main(String[] args) {
System.out.println(“请输入考试成绩:”);
Scanner input = new Scanner(System.in);
int score = input.nextInt(); // 接收键盘输入数据
if (score >= 90) { // 考试成绩>=90
System.out.println(“优秀”);
} else if (score >= 80) { // 90>考试成绩>=80
System.out.println(“良好”);
} else if (score >= 60) { // 80>考试成绩>=60
System.out.println(“中等”);
} else { // 考试成绩<60
System.out.println(“差”);
}
}
当考试成绩为 90 分以上时,则执行第一个 if 语句,下面的 3 个条件判断语句不会执行;当考试成绩为 80 分以上 90 分以下时,则执行第一个 else if 语句;当考试成绩在 60~80 分,并且包含 60 分的成绩,则执行第二个 else if 语句;如果上述 3 个条件都不满足,则执行 else 语句。
程序运行后的输出效果如下所示:
请输入考试成绩:
100
优秀
请输入考试成绩:
88
良好
请输入考试成绩:
50
差
嵌套 if 的使用
在复杂的业务逻辑中,可以使用多层的条件判断代码是否执行。
嵌套 if 的语法格式如下:
if(表达式1) {
if(表达式2) {
语句块1;
} else {
语句块2;
}
} else {
if(表达式3) {
语句块3;
} else if(表达式4) {
语句块4;
} else {
if(表达式n) {
语句块n;
} else {
语句块n+1;
}
}
}
在上述格式中,应该注意每一条 else 与离它最近且没有其他 else 对应的 if 相搭配。
示例:
活动计划安排,如果今天是工作日,去上班;如果今天是周末,则出去游玩;同时,如果周末天气晴朗,去室外游乐场游玩,否则去室内游乐场游玩。实现代码如下:
public static void main(String[] args) {
String today = “周末”;
String weather = “晴朗”;
if (today.equals(“周末”)) {
if (weather.equals(“晴朗”)) {
System.out.println(“去室外游乐场游玩”);
} else {
System.out.println(“去室内游乐场游玩”);
}
} else {
System.out.println(“去上班”);
}
}
如上述代码所示,today 满足 if 语句的“today.equals(“周末”)”条件,接着测试 weather 是否满足“weather.equals(“晴朗”)”条件,满足该条件输出“去室外游乐场游玩”。
3.1.2 switch case结构
switch 语句格式
switch 语句是 Java 的多路分支语句。在现实业务中,许多场景需要我们从多个固定的值中选出一个,执行该数值对应的操作。比如,在一周七天,当输入1-7会打印不同的星期。
对应这样的业务场景,我们可以使用switch选择结构。
switch 语句的基本语法形式如下所示:
switch(表达式) {
case 值1:
语句块1;
break;
case 值2:
语句块2;
break;
…
case 值n:
语句块n;
break;
default:
语句块n+1;
break;
}
其中,switch、case、default、break 都是 Java 的关键字。
1)switch
表示“开关”,这个开关就是 switch 关键字后面小括号里的值,小括号里要放一个整型变量或字符型变量。表达式必须为 byte,short,int,char类型。但是jdk7之后,switch也支持对string表达式的识别。只能是 java.lang.String 类型,不能是 StringBuffer 或 StringBuilder 这两种字符串的类型。
2)case
表示“情况,情形”,case 标签可以是:
类型为 char、byte、 short 或 int 的常量表达式。
枚举常量。
从 Java SE 7 开始, case 标签还可以是字符串字面量。
String input = …;
switch (input.toLowerCase()) { // toLowerCase用于将大写字符转换为小写
case “yes”:
…
break;
}
当在 switch 语句中使用枚举常量时,不必在每个标签中指明枚举名,可以由 switch 的表达式值确定。例如:
Size sz = …;
switch (sz) {
case SMALL: // no need to use Size.SMALL
…
break;
…
}
注意:重复的 case 值是不允许的。
3)default
表示“默认”,即其他情况都不满足。default 后要紧跟冒号,default 块和 case 块的先后顺序可以变动,不会影响程序执行结果。通常,default 块放在末尾,也可以省略不写。
4)break
表示“停止”,即跳出当前结构。
如果在 case 分支语句的末尾没有 break 语句,有可能触发多个 case 分支。那么就会接着执行下一个 case 分支语句。这种情况相当危险,常常会引发错误。
switch语句执行流程图:
通过流程图可以得知,switch语句将表达式的值与每个case中的目标值进行匹配,如果找到了匹配的值,会执行对应case后的语句,如果没找到任何匹配的值,就会执行default后的语句。break的作用是跳出switch语句。
示例:
在节目的抽奖环节里,节目组会根据每位嘉宾的座位号来进行抽奖游戏,根据不同的号码来决定奖项的大小。使用 switch 语句编写 Java 程序来完成奖项分配,其实现代码如下。
public static void main(String[] args) {
System.out.println(“请输入座位号码:”);
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
switch (num) {
case 8:
System.out.println(“恭喜你,获得了三等奖!”);
break;
case 88:
System.out.println(“恭喜你,获得了二等奖!”);
break;
case 888:
System.out.println(“恭喜你,获得了一等奖!”);
break;
default:
System.out.println(“谢谢参与!”);
break;
}
}
当用户输入的号码为 888 时,获取的 num 值为 888,则与第三个 case 后的值匹配,执行它后面的语句,输出“恭喜你,获得了一等奖!”,然后执行 break 语句,跳出整个 switch 结构。如果输入的号码与 case 中的值都不匹配,则执行 default 后的语句。
程序执行结果如下所示:
请输入座位号码:
888
恭喜你,获得了一等奖!
请输入座位号码:
88
恭喜你,获得了二等奖!
请输入座位号码:
66
谢谢参与!
示例:
键盘输入对应1-7,输出对应的中文日期:
public static void main(String[] args) {
String weekDate = “”;
Calendar calendar = Calendar.getInstance(); // 获取当前时间
int week = calendar.get(Calendar.DAY_OF_WEEK) - 1; // 获取星期的第几日
switch (week) {
case 0:
weekDate = “星期日”;
break;
case 1:
weekDate = “星期一”;
break;
case 2:
weekDate = “星期二”;
break;
case 3:
weekDate = “星期三”;
break;
case 4:
weekDate = “星期四”;
break;
case 5:
weekDate = “星期五”;
break;
case 6:
weekDate = “星期六”;
break;
}
System.out.println("今天是 " + weekDate);
}
本程序首先获取当前的星期值,然后使用 switch 语句判断 week 的值:0 表示星期日,1 表示星期一,2 表示星期二……以此类推,6 表示星期六。只要 week 值与 case 值相符合,则程序将执行该 case 中的语句,并跳出 switch 语句,输出结果。
运行程序,输出的结果如下:
今天是星期五
switch注意事项
(1)switch表示这是switch语句
(2)表达式的取值只能是:byte,short,int,char,JDK5以后可以是枚举,JDK7以后可以是String
(3)如同if语句当中的else,default不是必须存在的,与if语句不同,switch语句只能完成具体值的选择,而不能指定取值区间,case后面跟的是要和表达式进行比较的值
(4)语句体部分可以是一条或多条语句
(5)break表示中断,结束的意思,可以结束switch语句,default语句表示所有情况都不匹配的时候,就执行该处的内容,和if语句的else相似。
(6)case条件只判断一次,在判断完一次case条件后,所有的case判断语句将不再起作用,而剩余语句征程执行。这是switch语句的穿透。(了解)
3.1.3 if 语句和 switch 语句的区别
if 和 switch 语句都表示条件语句,可以从使用效率和实用性两方面加以区分。
-
从使用效率上区分
从使用效率上区分,在对同一个变量的不同值作条件判断时,既可以使用 switch 语句,也可以使用 if 语句。使用 switch 语句的效率更高一些,尤其是判断的分支越多,越明显。 -
从实用性上区分
从语句的实用性角度区分,switch 语句不如 if 条件语句,if 语句是应用最广泛和最实用的语句。 -
何时使用 if 语句和 switch 语句
在程序开发的过程中,何时使用 if 语句和 switch 语句,需要根据实际情况而定,应尽量做到物尽其用。不能因为 switch 语句的效率高就一直使用,也不能因为 if 语句常用就不用 switch 语句。需要根据实际情况,具体问题具体分析,使用最适合的条件语句。一般情况下,对于判断条件较少的,可以使用 if 条件语句,但是在实现一些多条件的判断中,最好使用 switch 语句。
3.1.4 本章小结
本章总结:
Java常见的选择语句,包括如下形式:
1.基本的if选择语句,可以处理单一或组合条件的情况。
2.if-else选择结构:可以处理简单的条件分支情况。
3.多重if选择结构:可以处理连续区间的条件分支情况。
4.嵌套if选择结构:可以处理复杂的条件分支情况。
5.当需要多重分支并且条件判断是等值判断的情况下,使用switch语句代替多重if语句会更简单,代码结构更清晰易读。在使用switch选择结构时不要忘记每个case的最后写上break语句。
课后作业:
1、输入一个学生的成绩,如果成绩及格(60分以上),请打印出来。横线处应该写( A )
public class IfTest{
public static void main(String args[]){
double cj=56;
if( ){
System.out.println(“成绩:”+cj+”为及格!”);
}
}
}
A、cj>=60 B、cj=60 C、cj60 D、cj<=60
2、输入一个学生的成绩,如果成绩大于等于60分,请打印及格,否者为不及格。横线处应该写( B )
public class IfElseTest{
public static void main(String args[]){
double cj=78;
{
System.out.println(“成绩:”+cj+”为及格!”);
} {
System.out.println(“成绩:”+cj+”为不及格!”);
}
}
}
A、if(cj60) else
B、if(cj>=60) else
C、if(cj>=60) if
D、if(cj=60) else
3、输入一个学生的成绩:如果成绩>=90,并且成绩<=100,请打印出优秀,如果成绩>=80,请打印出良好,如果成绩>=60,请打印出及格,其他情况为不及格。
横线处应该写( D )。
import java、util、Scanner;
public class IfElseIfTest{
public static void main(String args[]){
System、out、println(“请输入成绩(0-100):”);
Scanner s=new Scanner(System、in);
double cj=s、nextDouble();
if( ){
System.out.println(cj+”分为:优秀!”);
} {
System.out.println(cj+”分为:良好!”);
}else if(cj>=60){
System.out.println(cj+”分为:及格!”);
}else{
System.out.println(cj+”分为:不及格!”);
}
}
A、cj>=90||cj<=100 else if(cj>80)
B、cj>=90&&cj<=100 else if(cj==80)
C、cj>=90||cj<=100 else if(cj<=80)
D、cj>=90&&cj<=100 else if(cj>=80)
4 、if的条件语句是( B )类型的。
A、int B、boolean C、String D、double
5、int a=3,b=4;if(a>b){a++;b–;} 的执行结果是( A )。
A、a=3 b=4 B、a=4 b=3 C、a=3 b=3 D、a=4 b=4
6、public class SwitchTest{
public static void main(String args[]){
int cj=98;
switch(cj/10){
case 10:case9:
System.out.println(”优秀”);
case 8:
System.out.println(”良好”);
case 7:case 6:
System.out.println(”及格”);break;
default:
System.out.rintln(”不及格”);
}
}
}输出结果为( C )
A、优秀 B、及格 C、优秀良好及格 D不及格
7、public class JMonth {
public static void main(String[] arg){
int month = 13;
switch(month){
case 12:
case 1:
case 2: System.out.println(“冬季”); break;
case 3:
case 4:
case 5: System.out.println(“春季”); break;
case 6:
case 7:
case 8: System.out.println(“夏季”); break;
case 9:
case 10:
case 11: System.out.println(“秋季”);break;
default: System.out.println(“没有这个月份!请重新输入!”);
}
}
}输出结果为( A )
A、没有这个月份!请重新输入、 B、冬季 C、春季 D、null
8、每个 case 后面跟一个要比较的值和( A )
A、冒号 B、分号 C、引号 D、逗号
9、下列语句执行后,k的值为( B )
int x=6,y=10,k=5;
switch(x%y){
case 0:k=xy;
case 6:k=x/y;
case 12:k=x-y;
default:k=xy-x;
}
A、60 B、5 C、0 D、54
10、每个 case 后面跟一个要比较的值和( A )
A、冒号 B、分号 C、引号 D、逗号
3.2 循环语句
循环是程序中的重要流程结构之一。循环语句能够使程序代码重复执行,适用于需要重复一段代码直到满足特定条件为止的情况
循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体。当反复执行这个循环体时,需要在合适的时候把循环条件改为假,从而结束循环,否则循环将一直执行下去,形成死循环
循环语句可能包含如下 4 个部分。
(1)循环变量(变量初始化):用于计算循环次数的变量。
(2)循环条件(布尔表达式):这是一个boolean 表达式,这个表达式能决定是否执行循环体。
(3)循环变量改变(步进表达式):这个部分在一次循环体结束后,下一次循环判断条件执行前执行。通过用于控制循环条件中的变量,使得循环在合适的时候结束。
(4)循环逻辑内容(循环体):这个部分是循环体语句,也就是我们要多次做的事情。
3.2.1 while循环
while 语句是一种先判断的循环结构,可以在一定条件下重复执行一段代码。该语句需要判断一个测试条件,如果该条件为真,则执行循环语句(循环语句可以是一条或多条),否则跳出循环。
while 循环语句的语法结构如下:
while(条件表达式) {
语句块;
}
执行流程:
执行顺序: ①②③④>②③④>②③④… ②不满足为止。
①负责完成循环变量初始化。
②负责判断是否满足循环条件,不满足则跳出循环。
③具体执行的语句。
④循环后,循环变量的变化情况。
while 循环语句执行流程图
示例:
使用 while 语句计算 10 的阶乘,其具体代码如下所示。
public static void main(String[] args) {
int i = 1;
int n = 1;
while(i <= 10) {
n=ni;
i++;
}
System.out.println(“10的阶乘结果为:”+n);
}
在上述代码中,定义了两个变量 i 和 n,循环每执行一次 i 值就加 1,判断 i 的值是否小于等于 10,并利用 n=ni 语句来实现阶乘。当 i 的值大于 10 之后,循环便不再执行并退出循环。
运行程序,执行的结果如下所示:
10 的阶乘结果为:3628800
3.2.2 do-while循环
如你刚才所见,如果 while 循环一开始条件表达式就是假的,那么循环体就根本不被执行。然而,有时需要在开始时条件表达式即使是假的情况下,while 循环至少也要执行一次。换句话说,有时你需要在一次循环结束后再测试中止表达式,而不是在循环开始时。
Java就提供了这样的循环:do-while循环。do-while 循环语句也是 Java 中运用广泛的循环语句,它由循环条件和循环体组成,但它与 while 语句略有不同。do-while 循环语句的特点是先执行循环体,然后判断循环条件是否成立。
do-while 语句的语法格式如下:
do {
语句块;
}while(条件表达式);
执行流程:
执行顺序: ①③④>②③④>②③④… ②不满足为止。
①负责完成循环变量初始化。
②负责判断是否满足循环条件,不满足则跳出循环。
③具体执行的语句
④循环后,循环变量的变化情况
while 语句后必须以分号表示循环结束,其运行流程如图所示。
图 do-while 循环语句的执行流程
示例:
编写一个程序,计算 10 的阶乘。使用 do-while 循环的实现代码如下所示。
public static void main(String[] args) {
int number = 1,result = 1;
do {
result*=number;
number++;
}while(number <= 10);
System.out.print(“10阶乘结果是:”+result);
}
程序运行后输出结果如下:
10 阶乘结果是:3628800
示例:
在一个图书系统的推荐图书列表中保存了 50 条信息,现在需要让它每行显示 10 条,分 5 行进行显示。下面使用 do-while 循环语句来实现这个效果,其具体代码如下所示。
public static void main(String[] args) {
int bookIndex = 1;
do {
System.out.print(bookIndex+“\t”);
if(bookIndex%10 == 0) {
System.out.println();
}
bookIndex++;
}while(bookIndex<51);
}
在上述代码中, 声明一个变量 bookIndex 用来保存图书的索引,该变量赋值为 1 表示从第一本开始。在 do-while 循环体内,首先输出了 bookIndex 的值,然后判断 bookIndex 是否能被 10 整除,如果可以则说明当前行已经输出 10 条,用 System.out.println() 语句输出了一个换行符。之后使 bookIndex 加 1,相当于更新当前的索引。最后在 while 表达式中判断是否超出循环的范围,即 50 条以内。
运行程序,执行的结果如下所示。
1 2 3 4 5 6 7 8 9 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
3.2.3 for 循环
for 语句是应用最广泛、功能最强的一种循环语句。大部分情况下,for 循环可以代替 while 循环、do while 循环。
for 语句是一种在程序执行前就要先判断条件表达式是否为真的循环语句。假如条件表达式的结果为假,那么它的循环语句根本不会执行。for 语句通常使用在知道循环次数的循环中。
for 语句语法格式如下所示。
for(初始化表达式①;布尔表达式②;步进表达式④){
循环体③
}
for 循环中 3 个条件表达式的含义。
①负责完成循环变量初始化
②负责判断是否满足循环条件,不满足则跳出循环
③具体执行的语句
④循环后,循环条件所涉及变量的变化情况
for 循环语句执行的过程为:首先执行条件表达式 ① 进行初始化,然后判断条件表达式 ②的值是否为 true,如果为 true,则执行循环体语句块③;否则直接退出循环。最后执行表达式 ④,改变循环变量的值,至此完成一次循环。接下来进行下一次循环,直到条件表达式 ②的值为 false,才结束循环,其运行流程如图所示。
与前面循环类似的是,如果循环体只有一行语句,那么循环体的大括号可以省略。
示例:
同样是计算 5 的阶乘,使用 for 循环的实现代码如下:
public static void main(String[] args) {
int result = 1;
for (int number = 1; number <= 5; number++) {
result *= number;
}
System.out.print(“5 的阶乘结果是:” + result); // 输出"5的阶乘结果是:120"
}
上述语句的含义可以理解为,将 number 变量的值从 1 开始,每次递增 1,直到大于 5 时终止循环。在循环过程中,将 number 的值与当前 result 的值进行相乘。
for 语句中初始化、循环条件以及迭代部分都可以为空语句(但分号不能省略),三者均为空的时候,相当于一个无限循环。下面对这些情况依次进行介绍。
1.条件表达式 ①为空
for 语句中条件表达式 ① 的作用可以在程序的其他位置给出,所以当条件表达式 ①为空时,for 语句后面括号内其他条件表达式执行的顺序不变。
使用 for 语句的这种形式计算 1~100 所有奇数的和。
public static void main(String[] args) {
int result = 0;
int number = 1; // 相当于for语句的第1个表达式
for (; number < 101; number++) {
if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
result += number;
}
System.out.print(“100 以内所有奇数和为:” + result);
}
执行后的输出结果如下:
100 以内所有奇数和为:2500
2.条件表达式 ② 为空
当 for 语句中条件表达式② 为空时,将没有循环的终止条件。此时 for 语句会认为条件表达式② 的值总是为真,循环无限制执行下去。因此,为了使循环达到某种条件时退出,需要在语句块中进行逻辑判断,并使用 break 语句来跳出循环,否则将产生死循环。
同样是计算 1~100 所有奇数的和,使用这种方式的代码如下。
public static void main(String[] args) {
int result = 0;
for (int number = 1;; number++) {
if (number > 100)
break; // 相当于for语句的表达式2,满足时就退出for循环
if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
result += number;
}
System.out.print(“100 以内所有奇数和为:” + result);
}
3.条件表达式③为空
当 for 语言中条件表达式③为空时,也就没有设置控制变量的表达式,即每次循环之后无法改变变量的值,此时也无法保证循环正常结束。
同样是计算1~100 所有奇数的和,使用这种方式的代码如下:
public static void main(String[] args) {
int result = 0;
for (int number = 1; number < 101;) {
if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
result += number;
number++; // 相当于for语句的条件表达式3,每次递增1
}
System.out.print(“100 以内所有奇数和为:” + result);
}
如果没有循环体语句,number 变量的值为 1,永远小于 101,因此将无法结束循环,形成无限循环。在上面代码中将 number 的递增语句放在 for 循环体内,效果与完整 for 语句功能相同。
4.3 个条件表达式都为空
在 for 循环语句中,无论缺少哪部分条件表达式,都可以在程序的其他位置补充,从而保持 for 循环语句的完整性,使循环正常进行。
当 for 语句中循环体全为空时,即没有循环初值,不判断循环条件,循环变量不增值,此时无条件执行循环体,形成无限循环或者死循环。对于这种情况,读者在使用时应该尽量避免。
示例:
计算 1~100 所有奇数的和,使用这种方式的代码如下:
public static void main(String[] args) {
int result = 0;
int number = 1; // 相当于for语句的条件表达式1
for (;😉 {
if (number > 100)
break; // 相当于for语句的条件表达式2
if (number % 2 != 0) // 如果不能整除2,说明是奇数,则进行累加
result += number;
number++; // 相当于for语句的条件表达式3
}
System.out.print(“100 以内所有奇数和为: " + result);
}
示例:
编写一个 Java 程序,统计某超市上半年的总销售量,要求由用户输入每月的销量。使用 for 循环的实现代码如下。
public static void main(String[] args) {
int sum = 0;
int num = 0;
Scanner sc = new Scanner(System.in);
for (int i = 1; i <= 6; i++) {
System.out.println(“请输入第” + i + " 个月的销售数量:”);
num = sc.nextInt();
sum += num;
}
System.out.println(“上半年的销售总量为:” + sum);
}
在该程序中, 声明循环变量 i,控制循环的次数,它被初始化为 1。每执行一次循环,都要对 i 进行判断,看其值是否小于等于 6,条件成立则继续累加成绩,否则退出循环。
每执行完一次循环体,都会对 i 累加 1。如此循环重复,直到 i 的值大于 6 时停止循环。此时退出 for 循环体,执行最下方的语句输出累加的销售总量。
运行程序,执行结果如下所示。
请输入第1 个月的销售数量:
6840
请输入第2 个月的销售数量:
5449
请输入第3 个月的销售数量:
6546
请输入第4 个月的销售数量:
2400
请输入第5 个月的销售数量:
908
请输入第6 个月的销售数量:
8048
上半年的销售总量为:30191
一般选择循环变量时,习惯选择 i、j、k 来作为循环变量。
for、do-while 和 while 的区别
我们学习了 do-while 和 while 循环,我们又学习了 for 循环。总结他们之间的区别如下表所示。
表 2 for、do-while和while的区别
名称 概念 适用场景 特点
for 根据循环次数限制做多少次重复操作 适合循环次数是已知的操作 初始化的条件可以使用局部变量和外部变量
使用局部变量时,控制执行在 for 结束后会自动释放,提高内存使用效率。
且变量在 for 循环结束后,不能被访问。
先判断,再执行
while 当满足什么条件的时候,才做某种操作 适合循环次数是未知的操作 初始化的条件只能使用外部变量,且变量在 while 循环结束后可以访问
先判断,再执行
do-while 先执行一次,在判断是否满足条件 适合至少执行一次的循环操作 在先需要执行一次的情况下,代码更加简洁。
先执行一次,再判断
示例:
分别用 for、do-while 和 while 求出 1-10 的和。
1)使用for循环
代码如下:
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i < 11; i++) {
sum = sum + i;
}
System.out.println(sum);
}
运行结果为 55。
2)使用 do-while 循环
代码如下:
public static void main(String[] args) {
int sum = 0;
int i = 1;
do {
sum = sum + i;
i++;
} while (i < 11);
System.out.println(sum);
}
运行结果为 55。
3)使用 while 循环
代码如下:
public static void main(String[] args) {
int sum = 0;
int i = 1;
while (i < 11) {
sum = sum + i;
i++;
}
System.out.println(sum);
}
运行结果为 55。
从上边代码可以看出 for 语句明显更加简练,因为知道循环次数
3.2.4 循环嵌套
循环嵌套并不是一个新的知识点。只是在循环格式中嵌套使用了循环。
如for循环可以嵌套for循环:
for(初始化表达式; 循环条件; 操作表达式) {
………
for(初始化表达式; 循环条件; 操作表达式) {
执行语句
………
}
………
}
各种循环之间都可以发生嵌套,根据情况具体分析即可。
示例:
输出如下图形:
解析:
①外层循环的意义:让内层循环进行多少次循环
②内层循环的循环体全部执行后,外层循环才进行了一次
③技巧:外层循环控制行,内层循环控制列
for(int i=1;i<=3;i++){
for(int j=1;j<=10;j++){
System.out.print(“*”);
}
System.out.println();
}
输出结果如下:
示例:
输出如下图形:
*
**
for(int i=1;i<=3;i++){
for(int j=1;j<=i;j++){
System.out.print(“*”);
}
System.out.println();
}
总结:
1:这些图形是由星号()、空格等符号组成的,从上到下、从左至右地打印符号,就形成了一个图形。
2:重复地打印符号,我们就要用到循环结构,由于是从上到下、从左至右,我们要用嵌套的循环结构。
3:从上到下地打印符号,即一行一行地打印,对应了外层循环,外循环变量控制行数。
每一行,从左至右地打印若干个符号,对应了内层循环,内循环变量控制每行打印的符号数量。
嵌套循环扩展练习:
3排同学进行报数,每组5名同学,打印出我是第x排,第x个!
/
大毛,二毛,三毛,四毛,小明
小芳,杨幂,赵丽颖,高圆圆,杨颖
c罗,梅西,大罗,内马尔,柳岩
我是第1排,第1个!
我是第1排,第2个!
我是第1排,第3个!
我是第1排,第4个!
我是第1排,第5个!
我是第2排,第1个!
我是第2排,第2个!
…
*/
for(int i=0; i<3; i++){//外层循环可以控制打印的行数
//System.out.println(“我是第”+(i+1)+“排”);
for(int j=0; j<5; j++){//内层循环可以控制每行打印几个
//System.out.println(“我是第”+(j+1)+“个”);
dSystem.out.println(“我是第”+(i+1)+“排,第”+(j+1)+“个!”);
}
}
执行结果如下:
3.2.5 break 语句
某些时候需要在某种条件出现时强行终止循环,而不是等到循环条件为 false 时才退出循环。此时,可以使用 break 来完成这个功能。
break 用于完全结束一个循环,跳出循环体。不管是哪种循环,一旦在循环体中遇到 break,系统将完全结束该循环,开始执行循环之后的代码。
break运行规律
不需要判断任何条件,只要遇到break便直接跳出执行后续代码。会完全跳出选择或者循环结构。
break只能跳出最近的代码块,不能跨越多级代码块。
如:
for(int i=0; i<10; i++) {
if(i==5) {
break;
}
System.out.println(“我爱Java”+i);
}
//会从0-4输出5次“我爱Java”
示例:
小明参加了一个 1000 米的长跑比赛,在 100 米的跑道上,他循环地跑着,每跑一圈,剩余路程就会减少 100 米,要跑的圈数就是循环的次数。但是,在每跑完一圈时,教练会问他是否要坚持下去,如果回答 y,则继续跑,否则表示放弃。
使用 break 语句直接强行退出循环的示例如下:
public static void main(String[] args) {
Scanner input = new Scanner(System.in); // 定义变量存储小明的回答
String answer = “”; // 一圈100米,1000米为10圈,即为循环的次数
for (int i = 0; i < 10; i++) {
System.out.println(“跑的是第” + (i + 1) + “圈”);
System.out.println(“还能坚持吗?”); // 获取小明的回答
answer = input.next(); // 判断小明的回答是否为y?如果不是,则放弃,跳出循环
if (!answer.equals(“y”)) {
System.out.println(“放弃”);
break;
}
// 循环之后的代码
System.out.println(“加油!继续!”);
}
}
该程序运行后的效果如下所示:
跑的是第1圈
还能坚持吗?
y
加油!继续!
跑的是第2圈
还能坚持吗?
y
加油!继续!
跑的是第3圈
还能坚持吗?
n
放弃
尽管 for 循环被设计为从 0 执行到 10,但是当小明的回答不是 y 时,break 语句终止了程序的循环,继续执行循环体外的代码,输出“加油!继续!”。
break 语句能用于任何 Java 循环中,包括人们有意设置的无限循环。在一系列嵌套循环中使用 break 语句时,它将仅仅终止最里面的循环。例如:
public static void main(String[] args) {
// 外循环,循环5次
for (int i = 0; i < 5; i++) {
System.out.print(“第” + (i + 1) + “次循环:”);
// 内循环,设计为循环10次
for (int j = 0; j < 10; j++) {
// 判断j是否等于3,如果是,则终止循环
if (j == 3) {
break;
}
System.out.print("内循环的第" + (j + 1) + "次循环\t");
}
System.out.println();
}
}
该程序运行结果如下所示:
第1次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第2次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第3次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第4次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
第5次循环:内循环的第1次循环 内循环的第2次循环 内循环的第3次循环
从程序运行结果来看,在内部循环中的 break 语句仅仅终止了所在的内部循环,外部循环没有受到任何的影响。
注意:一个循环中可以有一个以上的 break 语句,但是过多的 break 语句会破坏代码结构。switch 循环语句中的 break 仅影响 switch 语句,不会影响循环。
编写一个 Java 程序,允许用户输入 6 门课程成绩,如果录入的成绩为负则跳出循环;如果录入 6 门合法成绩,则计算已有成绩之和。
使用 break 语句的实现代码如下:
public static void main(String[] args) {
int score; // 每门课的成绩
int sum = 0; // 成绩之和
boolean con = true; // 记录录入的成绩是否合法
Scanner input = new Scanner(System.in);
System.out.println(“请输入学生的姓名:”);
String name = input.next(); // 获取用户输入的姓名
for (int i = 1; i <= 6; i++) {
System.out.println(“请输入第” + i + “门课程的成绩:”);
score = input.nextInt();// 获取用户输入的成绩
if (score < 0) { // 判断用户输入的成绩是否为负数,如果为负数,终止循环
con = false;
break;
}
sum = sum + score; // 累加求和
}
if (con) {
System.out.println(name + “的总成绩为:” + sum);
} else {
System.out.println(“抱歉,分数录入错误,请重新录入!”);
}
}
运行程序,当用户录入的分数低于 0 时,则输出“抱歉,分数录入错误,请重新录入!”信息,否则打印学生的总成绩。输出结果如下所示。
请输入学生的姓名:
zhangpu
请输入第1门课程的成绩:
100
请输入第2门课程的成绩:
75
请输入第3门课程的成绩:
-8
抱歉,分数录入错误,请重新录入!
请输入学生的姓名:
zhangpu
请输入第1门课程的成绩:
100
请输入第2门课程的成绩:
68
请输入第3门课程的成绩:
73
请输入第4门课程的成绩:
47
请输入第5门课程的成绩:
99
请输入第6门课程的成绩:
84
zhangpu的总成绩为:471
在该程序中,当录入第 3 门课的成绩时,录入的成绩为负数,判断条件“score<0”为 true,执行“con=false”,用 con 来标记录入是否有误。接着执行 break 语句,执行完之后程序并没有继续执行条件语句后面的语句,而是直接退出 for 循环。之后执行下面的条件判断语句,判断 boolean 变量的 con 是否为 true,如果为 true,则打印总成绩;否则打印“抱歉,分数录入错误,请重新录入!”。
3.2.6 continue语句
有时强迫一个循环提早反复是有用的,也就是,你可能想要继续运行循环,但是要忽略这次重复剩余的循环体的语句,所以 Java 提供了 continue 语句。continue 语句是 break 语句的补充。
continue 语句与 break 语句一样, 它将中断正常的控制流程。continue 语句将控制转移到最内层循环的首部。
continue 语句是跳过循环体中剩余的语句而强制执行下一次循环,其作用为结束本次循环,即跳过循环体中下面尚未执行的语句,接着进行下一次是否执行循环的判定。
如:
for(int i=0; i<10; i++) {
if(i==5) {
continue;
}
System.out.println(“我爱Java”+i);
}
//会从0-4、6-9输出9次“我爱Java”
continue 语句类似于 break 语句,但它只能出现在循环体中。它与 break 语句的区别在于:continue 并不是中断循环语句,而是中止当前迭代的循环,进入下一次的迭代。简单来讲,continue 是忽略循环语句的当次循环。
注意:continue 语句只能用在 while 语句、for 语句或者 foreach 语句的循环体之中,在这之外的任何地方使用它都会引起语法错误。
3.2.7 本章小结
本章总结
循环结构由循环条件和循环操作组成,只要条件满足,循环操作就会反复执行。
使用循环解决问题的步骤:分析循环条件和循环操作,套用循环的语法写出代码,检查循环能否退出。
编写循环结构时要注意循环变量的初值、循环变量值的改变和循环条件三者之间的关系,不要出现死循环。
可以使用break、continue语句控制循环流程,break语句用来终止某个循环,程序跳转到循环体外的语句;continue语句用来跳出本次循环,进入下一次循环。
本章作业
一、简答题
1.写出下面程序的运行结果:
public class ForBar {
public static void main(String[] args) {
int i = 0, j = 5;
tp: for (;😉 {
i ++;
for(;😉
if(i > --j) break tp;
}
System.out.println("i = " + i + ", j = “+ j);
}
}
2.读程序写结果。
public class Continue_exe {
public static void main(String[] args) {
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 != 0)
continue;
else
sum += i;
}
System.out.println(“和为:” + sum);
}
}
3.阅读下面的程序段,回答问题。
if ( x < 5 )
S ystem.out.print(” one “);
else{
if ( y < 5 )
System.out.print(” two “);
else
System.out.println(” three ");
}
问题:
(1)若执行前 x=6, y=8,该程序段输出是什么?
(2)若执行前 x=1, y=8,该程序段输出是什么?
4.阅读下面程序片段,试回答程序执行后n的值是多少?
int j=12,i=6,n=19;
switch(j-i){
case 5: n=n-i; break;
case 6: n=n+9;
case 7: n=n-i; break;
default:n=n*2;
}
5.阅读下面do-while程序片段,写出程序的执行结果。
int i=0,total=0;
do{
i=i+2;
System.out.println(“i=”+i);
total=total+(i++)*2;
}while(i<12);
System.out.println(“总数为:”+total);
6.阅读下列有关break语句的程序,写出程序的输出结果。
public class BreakTest {
public static void main(String[] args) {
int i = 3, j;
outer: while (i > 0) {
j = 3;
inner: while (j > 0) {
if (j < 2)
break outer;
System.out.println(j + “and” + i);
j–;
}
i–;
}
}
}
7.阅读下列有关continue语句的程序,写出程序的输出结果。
public class ContinueTest {
public static void main(String[] args) {
int n = 10;
for (int i = 1; i <= n; i++) {
if (n % i != 0)
continue;
System.out.print(i + “,”);
}
}
}
二、编程题
1.企业发放的奖金根据利润提成。利润低于或等于10万元时,奖金可提10%;利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%;20万到40万之间时,高于20万元的部分,可提成5%;40万到60万之间时高于40万元的部分,可提成3%;60万到100万之间时,高于60万元的部分,可提成1.5%,高于100万元时,超过100万元的部分按1%提成,在程序中设定一个变量为当月利润,求应发放奖金总数?
2.给定一个成绩a,使用switch结构求出a的等级。A:90-100,B:80-89,C:70-79,D:60-69,E:0~59。
3.假设某员工今年的年薪是30000元,年薪的年增长率6%。编写一个Java应用程序计算该员工10年后的年薪,并统计未来10年(从今年算起)总收入。
4.猴子第一天摘下若干个桃子,当即吃了一半,还不瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
5.输入一个数字,判断是一个奇数还是偶数。
6.编写程序, 判断一个变量x的值,如果是1,输出x=1,如果是5,输出x=5,如果是 10,输出x=10,除了以上几个值,都输出x=none。
7.判断一个数字是否能被5和6同时整除(打印能被5和6整除),或只能被5整除(打印能被5整除),或只能被6整除,(打印能被6整除),不能被5或6整除,(打印不能被5或6整除)
8.输入一个年份,判断这个年份是否是闰年。
9.输入一个0~100的分数,如果不是0~100之间,打印分数无效,根据分数等级打印A,B,C,D,E。
10.输入三个整数x,y,z,请把这三个数由小到大输出。
11.有一个不多于5位的正整数,求它是几位数,分别打印出每一位数字。
12.编写一个程序,计算邮局汇款的汇费。如果汇款金额小于100元,汇费为一元,如果金额在100元与5000元之间,按1%收取汇费,如果金额大于5000元,汇费为50元。汇款金额由命令行输入。
13.分别使用for循环,while循环,do循环求1到100之间所有能被3整除的整数的和。
14.输出0-9之间的数,但是不包括5。
15.编写一个程序,求整数n的阶乘,例如5的阶乘是12345。
16.编写一个程序,找出大于200的最小的质数。
17.由命令行输入一个4位整数,求将该数反转以后的数,如原数为1234,反转后的数位4321。