第一章 Java起步入门
Java 是一种面向对象编程语言,它支持面向对象的全部特征。学习Java语言首先需要了解其基本概念。本章首先介绍Java的起源和演进,之后介绍Java程序运行机制、JDK的安装和简单Java 程序的开发、Eclipse 集成开发环境的使用,最后简单介绍JShell交互式编程环境。
1.1 Java的起源与演进
Java是由Sun Microsystems的James Gosling等人在90年代初开发的面向对象编程语言,源自Green项目,旨在为嵌入式系统编写软件。Gosling最初考虑使用C++,但因其不足而创造了新语言,最初命名为Oak。因商标问题,Sun在1993年将其更名为Java。Java因其跨平台能力、效率、安全性和通用性而广受欢迎,在云计算和移动互联网时代具有巨大潜力。
1.1.1 Java的发展历程
Java语言具有强大的生命力,其原因之一是它像软件一样不断推出新版本。多年来,Java语言不断发展、演化和修订,使它一直站在计算机程序设计语言的前沿。从诞生以来,它已经做过多次或大或小的升级。
版本名称 | 别名 | 发布日期 |
Java Platform 1.0 | 1996-01-23 | |
Java Platform 1.1 | 1997-02-19 | |
Java Platform 1.2 | J2SE 1.2 | 1998-12-04 |
Java Platform 1.3 | J2SE 1.3 | 2000-05-08 |
Java Platform 1.4 | J2SE 1.4 | 2002-02-13 |
Java 5.0 | J2SE 5.0 | 2004-09-30 |
Java 6 | Java SE 6 | 2006-12-11 |
Java 7 | Java SE 7 | 2011-07-28 |
Java 8 | Java SE 8 | 2014-03-18 |
Java 9 | Java SE 9 | 2017-09-21 |
Java 10 | Java SE 10 | 2018-03-20 |
Java 11 | Java SE 11 | 2018-09-25 |
Java 12 | Java SE 12 | 2019-03-19 |
Java 13 | Java SE 13 | 2019-09-17 |
Java 14 | Java SE 14 | 2020-03-17 |
Java 15 | Java SE 15 | 2020-09-15 |
Java 16 | Java SE 16 | 2021-03-16 |
Java 17 | Java SE 17 | 2021-09-14 |
Java 18 | Java SE 18 | 2022-03-22 |
Java 19 | Java SE 19 | 2022-09-20 |
Java 20 | Java SE 20 | 2023-03-21 |
Java于1995年发布,1996年推出1.0版。1999年Java 2(J2SE)发布,标志第二代。2004年Java 5带来重大改进,版本号跃至“5”。Java 6(2006年)改进较小。2010年Java 7是Oracle收购Sun后的首版,添加多项功能。Java 8(2014年)引入Lambda表达式,简化多核编程。Java 9(2017年)后,Oracle每半年发布新版,最新为Java 18。本书将介绍各版本新特性。
1.1.2 Java语言的优点
Java之所以能在众多编程语言中脱颖而出,是因为其独特的优势,包括面向对象、平台独立、解释型、简洁、分布式、健壮、安全、可移植、高性能、多线程和动态性。下面重点介绍面向对象和平台独立的特性。
1. 面向对象
Java 是一种面向对象的语言,也就是说,它的代码都是基于类的,而这些类可以创建对象。在 Java 中,我们主要使用类和对象来组织代码,这与以前的过程式编程不同,后者主要使用函数或例程。尽管 Java 从版本 8 开始支持一些函数式编程特性,但它的核心仍然是面向对象的。
2. 平台独立
Java 最大的特点之一是它的程序可以在任何支持 Java 的平台上运行,而无需修改代码。这是因为 Java 程序不是直接编译成特定计算机的机器码,而是编译成一种叫做字节码的中间代码。这些字节码随后在 Java 虚拟机(JVM)上运行。只要你安装了相应平台的 Java 虚拟机,Java 程序就可以运行,这就实现了“一次编写,到处运行”的理念。
1.2. Java平台与运行机制
1.2.1 Java平台与应用领域
Java 是一种多功能的编程语言,适用于各种不同的应用场景。Java 平台主要分为三个版本,每个版本都针对特定的应用领域:
Java 标准版(Java SE):这个版本可以用来开发能够在个人电脑上独立运行的应用程序,比如桌面软件。它还包括 JavaFX,这是一种用于创建图形用户界面的工具。
Java 企业版(Java EE,现在称为 Jakarta EE):这个版本适用于开发服务器端的应用程序,比如网站后台。它支持多种技术,包括 Java Servlet、JavaServer Pages(JSP)和 JavaServer Faces(JSF)。
Java 微型版(Java ME):这个版本用于开发在小型设备上运行的应用程序,比如手机。它适用于资源有限的设备。
使用 Java,你可以开发各种类型的程序,比如:
控制台应用程序:在命令行界面下运行的程序。
窗口应用程序:带有图形用户界面的程序。
服务器端应用程序:在服务器上运行的程序,如网站后台。
嵌入式应用程序:在专门的设备上运行的程序,比如 Android 应用。
本书主要介绍 Java SE 编程,因为它是 Java 编程的基础。书中将使用 Java 17 版本,并介绍 Java 各个版本中的重要新功能和语言特性,以展示 Java 语言的最新发展。
1.2.2 JVM、JRE和JDK
Java程序写好之后,需要用到一个叫做javac的编译器来把它转换成一种中间格式,叫做字节码。这个字节码不是直接能在你的电脑上运行的,它需要在Java虚拟机(JVM)上跑。JVM就像是一个特殊的软件,它能在不同的操作系统上解释字节码,让Java程序能够在任何地方运行,这就是为什么我们说Java是跨平台的。
为了让Java程序运行,你还需要一堆已经写好的Java类库,这些类库提供了各种常用的功能,比如处理文件、网络通信等。JVM是一种运行字节码的应用程序。JRE则是一种包含JVM和Java类库的环境,JVM加上这些类库,就构成了Java运行时环境(JRE)。不过,从Java 11开始,Oracle不再单独发布JRE了。
1.3 建立开发环境
开发Java 程序必须首先下载和安装JDK,我们就可以编译和运行Java 程序。
1.3.1 JDK的下载与安装
从Oracle 官方网站www.oracle.com 免费下载JDK。
以下是jdk8快速访问地址
https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html
下拉选择版本下载
安装好后发现多出了几个目录
·bin目录:存放编译、执行和调试Java程序的工具。例如,javac.exe是Java编译器;java.exe 是Java解释器;jdb.exe是Java程序的调试工具;javadoc.exe是HTML格式的API文档生成器;jar.exe 是将.class文件打包成JAR文件的工具。
·conf 目录:存放一些配置文件。
•include 目录:存放本地代码编程需要的C头文件。
•jmods 目录:存放 JMOD格式的平台模块。创建自定义运行时映像需要它。
•legal目录:存放法律文件。
•lib 目录:存放开发工具所需要的附加类库和支持文件。
1.3.2 关于环境变量
安装完JDK后就可以在系统的任何位置编译和运行java程序了,可以按以下操作测试一下
Win+R 后输入 cmd 打开命令提示符窗口
在窗口内输入
javac
如果出现编译器选项则说明编译器正常
2.启动一个Windows的”命令提示符“窗口,在提示符下输入java -version,如果显示java版本号信息,说明解释器正常。
1.3.3 Java API文档
以下网址提供了在线 API文档:
https://docs.oracle.com/en/java/javase/17/docs/api/index.html
也可以将 Java API文档下载到本地计算机,下载地址如下:
http://www,.oracle.com/technetwork/java/javase/downloads/index.html
Oracle 还提供了一个 Java 在线教程。该教程介绍了 Java 语言的所有内容,是非常d 学习资源。也可以将该教程下载到本地计算机上,下载地址如下:
https://docs.oracle.com/javase/tutorial/
1.4 第一个Java程序
Java应用程序是独立的,可以直接在java平台上运行的程序。
1.4.1 Java程序开发步骤
图1-10 Java程序的编辑、编译和执行过程
开发Java程序通常分三步:
编辑源程序
编译源程序
执行或调试程序
程序1.1 HelloWorld.java
1.编辑源程序
可以使用任何文本编辑器(如 Windows 的记事本或 Sublime 编辑器)编辑 Java 源程序,也可以使用专门的集成开发环境(如Ecipse、IntelliJ IDEA等)。若使用Windows的记事本编写源程序,如下所示。
public class Demo{
public static void main(String[] args){
System.out.println(“Hello World!");
}
}
将上述文件保存后,启动一个Windows的”命令提示符“窗口,进入到该文件所在目录下,并输入文件名,如”Demo,java“,如图1-11所示。
图1-11 检查源程序是否存在
2.编译生成字节码
接下来,需要将 Demo.java 源文件编译成字节码文件。编译源文件需要使用 JDK的 javac命令,如图1-12所示:
图1-12 编译生成字节码
若源程序没有语法错误,该命令执行后。在当前目录下产生一个 Demo.class字节码文件,该文件的扩展名为.class,主文件名与程序中的类名相同,该文件也称为类文件。
图1-13 生成字节码文件
3.执行字节码
源程序编译成功生成字节码文件后可以使用Java解释器执行该程序。
注意,这里不要加上扩展名.class,运行结果如图1-14所示
图1-14 程序的运行结果
总结:
图1-15 开发Java程序的过程
1.4.2 第一个程序分析
下面对第一个程序中涉及的内容进行简要说明。
1.类定义
Java程序的任何代码都必须放到一个类的定义中,类的内容包括在代码块内,类的内容包括在代码块内,一个块(block)是以左花括号开始,以右花括结束的语句组。
本程用定及一个名为Demo的类,public为类的访问修饰符,clas为关键字,其后用一对大括号括起来,称为类体(class body)。
下面对第一个程序中涉及的内容进行简单说明。
2.mian()方法
Java应用程序的标志是类体中定义的一个main()方法,称为主方法。主方法是程序执行入口,它类似于C语言的main函数。main()方法的格式如下:
public static void main(String[] args){
......
}
本程序的main()方法中只有一行语句:System.out.println(“Hello World!");
该语句的功能是在标准输出设备上打印输出一个字符串,字符串字面值用双引号定界。Java程序的语句要以分号(;)结束。
System为系统类,out为该类中定义的静态成员,它是标准输出设备,通常指显示器。
println()是输出流 out中定义的方法,功能是打印输出字符串并换行。若不带参数,仅起到换行的作用。
另一个常用的方法是 print(),该方法输出后不换行。
4.源程序命名
在Java语言中,一个源程序文件被称为一个编译单元。它是包含一个或多个类定义的文件。Java编译器要求源程序文件必须以.Java为扩展名。当编译单元中有 public 类时,主文件名必须与 public类的类名相同(包括大小写)。
如本例的源程序文件名应为Demo.java。
若编译单元中没有public类,源程序的主文件名可以任意。
1.5 JShell交互式编程环境
JShell是JDK提供的一种命令行工具,称为Java REPL(Read-Eval-Print-Loop)。
安装了JDK并设置了Path环境变量后即可使用JShell。
图1-16 JShell运行界面
在JShell>提示符下,允许用户直接输入代码片段,其中包括
各种声明(类、接口、方法等)
表达式
各种语句)(控制结构)
图1-17 JShell执行语句
第2章 数据类型与运算符
2.1 Java数据类型
Java语言的数据类型可分为基本数据类型和引用数据类型两大类。
图2-1 Java语言的数据类型
2.1.1 基本数据类型
Java共有8种基本数据类型。基本数据类型在内存中所寸的位数固定,不依赖于所用的机器,这也正是Java跨平台的体现。各种基本数据类型在内存中所占位数及其取值范围如下表2-2所示。
图2-2 Java基本数据类型
2.1.2 引用数据类型
除基本数据外,Java还支持引用数据类型,其中包括类、接口、枚举、记录、注解和数组等。正是由于可以使用引用数据类型,才使Java可以编写面向对象程序。
图2-3 Java引用数据类型
类(包括抽象类)是 Java 语言最重要的引用数据类型,任何]ava 程序都离不开类的使用。有了类才能创建对象或实例,程序就是对实例进行操作。
接口是对类的一种扩展,它也是一种引用类型,但接口不能实例化。接口在类型的多继承和多态性具有广泛应用。
枚举是一种特殊的引用类型,它用来定义具有确定几个值的类型,比如交通灯有绿色、红色、黄色三种颜色,就可以定义一个枚举类型表示这三种颜色。
记录类型是 Java 16 引人的新特性,它主要用来声明用于存储数据的类,使用记录可使程序员不必自己定义访问方法,如 equals()、hashCode()和 toString()等。
注解类型以结构化的方式为程序元素(类、方法等)提供信息,这些信息能够被编译器、解释器等外部工具自动处理。
对于上述这些类型,可以使用Jave类库中定义的(如 Sysiemn 类),也可以使用程序员自己定义的,还可以使用第三方提供的类库。
数组是一种特殊的引用类型,它不需要程序员自己定义有关类型。只要声明和创建数组对象,就可以像其他引用类型实例一样使用数组。
2.2标识符与语句
2.2.1 Java标识符
在Java 程序中,标识符(identifier)用来为变量、方法和类型(类、接口等)命名。
java 语言规定,标识符必须以字母、下划线(_)或美元符($)开头,其后可以是字母、下划线、美元符或数字,长度没有限制。
例如:intTest, Manager_Name, _var, $Var,都是合法的标识符
不推荐使用无意义的单个字母命名标识符,而应该使用有意义的单词或单词组合为对象命名。Java标识符采用驼峰命名法,有两种形式:大写的CamelCase 和小写的 camelCase。
CamelCase 每个单词的首字母大写。类、接口用该方法命名
camelCase,第一个单词的首字母小写,变量和方法用该方法命名
标识符是区分大小写的,下面两个标识符是不同的。
myName , MyName
2.2.2 Java关键字
每种语言都定义了自己的关键字。所谓关键字(keywords)是该语言事先定义的一组词汇,这些词汇具有特殊的用途,用户不能将它们定义为标识符。Java 语言定义了下列 51个保留关键字。
abstract | continue | for | new | switch |
assert | default | goto | package | synchronized |
boolean | do | if | private | this |
break | double | implements | protected | throw |
byte | else | import | public | throws |
case | enum | instanceof | return | transient |
catch | extends | int | short | try |
char | final | interface | static | void |
class | finally | long | strictfp | volatile |
const | float | native | super | while |
2.2.3 变量与赋值
变量是在程序运行中其值可以改变的量。一个变量通常由数据类型****、变量名和变量值三**个要素组成。
Java中有两种类型的变量:基本类型的变量和引用类型的变量。
基本类型的变量:数值型(整数型和浮点型)、布尔型和字符型。
引用类型的变量:类、接口、枚举和数组等。
//变量在使用前必须先声明,然后初始化:
int number;// 类型名 变量名
int number = 100; //变量的初始化就是给变量赋初值:
int number = 100; //可以在声明的同时初始化变量:
2.2.4 语句
//下面是给变量赋值的语句
a = b + 5
//下面是一条变量声明语句
long seconds;
2.3 基本数据类型及字面值
字面值(literals)是某种类型值的表示形式。
字面值有三种类型:
基本类型的字面值:**基本类型的字面值有4种类型:整数型、浮点型、布尔型、字符型。**如123、-789为int型字面值,3.456、2e3为double型字面值,true、false为布尔型字面值,‘g’、‘我’为字符字面值
字符串字面值:用双引号定界的字符序列,如“Hello”是一个字符串字面值
null字面值
2.3.1 整数类型
Java提供4种整数类型,分别是byte型(字节型)、 short型(短整型)、 int型(整型)和long型(长整型)。
Java的整型字面值有四种表示方法:
十进制数,如0、257、-365
二进制数,以0b或0B开头的数,如0B00101010表示十进制数42。
八进制数,以0开头的数,如0124表示十进制数84,-012表示十进制数-10。
十六进制数,以0x或0X开头的整数,如0x124表示十进制数的292。
Java的整型变量使用byte、short、int、long等声明,下面是几个整型变量的定义。
byte num1 = 120;
short num2 = 1000;
int num3 = 99999999;
long num4 = 12345678900L; // 超出int值范围必须用L表示
byte a = 0b00101010; // 二进制形式
int b = 0200; // 八进制形式
long c = 0x1F; // 十六进制形式
System.out.println("a = " + a); // 输出:a = 42
System.out.println("b = " + b); // 输出:b = 128
System.out.println("c = " + c); // 输出:c = 31
注意:
//在给变量赋值时,不能超出该数据类型所允许的范围,否则发生编译错误。下面语句发生编译错误。
byte a = 200;
//编译错误说明类型不匹配,不能将一个int型的值转换成byte型值。因为200超出了byte型数据的范围(-128~127),因此编译器拒绝编译。
2.3.2 浮点类型
浮点类型的数就是数学上通常所说的实数。
在Java中由两种浮点类型的数据:float型和double型。这两种类型的数据在内存中所占的位数不同,float型占32位,double型占64位。所以分别称为单精度浮点数和双精度浮点数。且符合IEEE-754标准。
数据类型 字节 所占位数 数的范围
float 4 32 约1.4×10-45~3.4×1038
double 8 64 约4.9×10-432~1.7×10308
浮点型字面值有两种表示方法。
十进制数形式,由数字和小数点组成,且必须有小数点。 如:3.14
科学记数法形式 ,e之前必须有数字,e后面的指数必须为整数。4.5e+3
//浮点型变量使用float和double关键字定义,如下两行分别声明了两个浮点型变量pi和d:
double d = .00001005;
float pi = 3.1415926F; //float型字面值必须加F或f
System.out.println("double d = " + d); //输出结果为double d = 1.005E-5
System.out.println("float pi = " + pi); //输出结果为float pi = 3.1415925
浮点数的运算是不精确的,不适合做财务计算。因为浮点数计算可能存在舍入误差,而财务计算中的舍入误差是不能接受的。
需要精确而无舍入误差的数字计算,可以使用java.math.BigDecimal类。
2.3.3 字符类型
字符是程序中可以出现的任何单个符号。
Java使用Unicode为字符编码,Unicode字符集使用两个字节(16位)为字符编码,可表示65 536个字符。
字面值用单引号将字符括起来,大多数可见的字符都可用这种方式表示,如’a’、‘@’、'我’等。
有些特殊字符用转义序列来表示。用反斜杠(\)表示转义,如’\n’表示换行。
图2-4 常见的转义字符序列
2.3.4 布尔类型
布尔型字面值很简单,只有两个值true和false,分别用来表示逻辑真和逻辑假。
布尔型值使用boolean关键字声明,如下面语句声明了布尔型变量t并为其赋初值true
boolean t = true;
所有关系表达式的返回值都是布尔型的数据,如表达式10 < 9的结果为false。布尔型数据也经常用于选择结构和循环结构的条件中
2.4 字符串类型
Java程序中经常要使用字符串。字符串是字符序列,不属于基本数据类型,是一种引用类型。
//字符串是通过String类实现的。可用String声明和创建一个字符串。可以通过双引号定界符创建一个字符串字面值。
String s = "Java is cool.";
//注意,一个字符串字面值不能分在两行来写。例如,下面代码产生编译错误:
String s = "学而时习之,
不亦说乎?" ;
//对于较长的字符串,可以使用加号运算符(+)将两个字符串连接:
String s1 = "有朋自远方来” + ",不亦乐乎?";
String s2 = "人不知而不愠“
+ ",不亦君子乎?" ;
//可以将一个String和一个基本类型或者另一个对象连接在一起。例如,下面代码就是字符串常量和一个int型变量及double型变量连接。
int age = 25;
double salary = 8000;
System.out.println("我的年龄是:" + age); //输出结果是 我的年龄是25
System.out.println("我的工资是:" + salary); //输出结果是 我的工资是8000
字符串与其他类型值连接,系统首先将其他类型值转换为字符串,然后两个字符串再连接。
2.5 软件开发过程
软件开发过程是指软件设计思路和实现方法的一般过程。一般都是一个多阶段过程,通常包括需求确定、系统分析、系统设计、实现、测试、部署和维护。
这里重点讨论几个重要步骤:
理解问题。就是需求分析。
开发解决方案。算法是解决问题所需的一组逻辑步骤。
实现。也称为编码。
测试。测试的目的是发现程序的错误。
2.6数据类型转换
整型、浮点型、字符型数据可能需要混合运算或相互赋值,这就涉及类型转换的问题。
转换分为:
**自动类型转换**
**强制类型转换**
2.6.1自动类型转化
自动类型转换也称加宽转换,它是指将具有较少位数的数据类型转换为具有较多位数的数据类型。
byte b = 120;
int i = b; //字节型数据b自动转换为整型
图2-5 基本类型的自动转换
2.6.2 强制类型转换
强制类型转换:将位数较多的数据类型转换为位数较少的数据类型。
其语法是用圆括号运算符。例如:将double型数据转换为byte型数据。
double d = 200.5;
byte b = (byte)d; // 将double型值强制转换成byte型值
System.out.println(b); // 输出-56
一般来说,以下类型之间的转换需要进行强制转换:
从short到byte或者char
从char到byte或者short
从int到byte、short、或者char
从long到byte、short、char或者int
从float到byte、short、char、int或者long
从double到byte、short、char、int、long或者float
2.6.3 表达式类型自动提升
除了赋值可能发生类型转换外,在含有变量的表达式中也有类型转换的问题。
byte a = 40;
byte b = 50;
byte c = a + b; // 编译错误
c = (byte)(a + b); // 正确
int i = a + b;
补充:
Java中的浮点数通常保留15位有效数字,比如,圆周率在Java中用Math.PI常量表示,默认情况下输出它的值是3.141592653589793。假设希望将该值四舍五入保留4位小数,可以通过下面程序实现。
double pi = Math.PI;
pi = pi * 10000 + 0.5; // 将原值扩大10000倍,再加0.5
pi = (int) pi; // 强制转换成整数
pi = pi / 10000; // 再除以10000,达到四舍五入效果
System.out.println(pi);
2.7 运算符
表示各种不同运算的符号称为运算符(operator),参与运算的各种数据称为操作数(operand)。
表达式(expression)是由运算符和操作数按一定语法规则组成的符号序列。以下是合法表达式
(2 + 3) * (8 - 5)
a > b
每个表达式经过运算后都会产生一个确定的值。
按照功能划分 | 按照所需要的操作数个数划分 |
算术运算符 | 一元运算符 ++ a |
逻辑运算符 | 二元运算符 a && b |
关系运算符 | 三元运算符 a > b ? a**😗*b |
赋值运算符 | |
位运算符等 |
2.7.1 算术运算符
算术运算符一般用于对整型数和浮点数运算。
一元运算符:正(+)、负(-)、自增(++)、自减(–)4个。
二元运算符:加(+)、减(-)、乘(*)、 除(/)、取余数(%)5个
补充:
自増(++)和自减(–)运算符
”++“和”–”运算符主要用于对变量的操作,分别称为自增和自减运算符,“++”表示加1,“–”表示减1。它们又都可以使用在变量的前面或后面,如果放在变量前,表示给变量加1后再使用该变量;若放在变量的后面,表示使用完该变量后,表示使用完该变量再加1。
//例如,假设当前变量x的值为5,执行下面的语句后x和y的值如下所示
y = x++; //结果:y=5x=6
y = ++x; //结果:y=6x=6
y = x--; //结果:y=5x=4
y = --x; //结果:y=4x=4
//自增和自减运算符可用于浮点型变量,例如下列代码是合法的。
double d = 3.15;
d++ ; // 执行后 d的结果为 4.15
2.7.2 关系运算符
关系运算符(也称比较运算符)用来比较两个值的大小或是否相等。
运算符 | 含 义 | 运算符 | 含 义 |
> | 大于 | <= | 小于或等于 |
>= | 大于或等于 | == | 相等 |
< | 小于 | != | 不相等 |
2.7.3 逻辑运算符
!(逻辑非) & (逻辑与) | 逻辑或) ^(逻辑异或) && (短路与) || (短路或)
A | B | !A | A&B | A|B | A^B | A&&B | A||B |
false | false | true | false | false | false | false | false |
false | true | true | false | true | true | false | true |
true | false | true | false | true | true | false | true |
true | true | false | true | true | true | true | true |
true | true | false | true | true | false | true | true |
表2-1 逻辑运算的运算规则
2.7.4 赋值运算符
假设a=15,b=3
扩展赋值运算符 | 表达式 | 等价表达式 | 结果 |
+= | a+=b | a=a+b | 18 |
-= | a-=b | a=a-b | 12 |
*= | a*=b | a=a*b | 45 |
/= | a/=b | a=a/b | 5 |
%= | a%=b | a=a%b | 0 |
&= | a&=b | a=a&b | 3 |
|= | a|=b | a=a|b | 15 |
^= | a^=b | a=a^b | 12 |
<<<= | a<<<=b | a=a<<<b | 120 |
>>= | a>>=b | a=a>>b | 1 |
>>>= | a>>>=b | a=a>>>b | 1 |
表2-2 扩展的赋值运算符
2.7.5 位运算符
位运算是在整数的二进制位上进行的运算。
位运算在整数的二进制位上操作,有两类:
位逻辑运算
移位运算
假设a=10,b=3
运算符 | 功能 | 示例 | 结果 |
~ | 按位取反 | ~a | -11 |
& | 按位与 | a&b | 2 |
| | 按位或 | a|b | 11 |
^ | 按位异或 | a^b | 9 |
<< | 按位左移 | a<<b | 80 |
>> | 按位右移 | a>>b | 1 |
>>> | 按位无符号右移 | a>>>b | 1 |
表2-3 位运算符
A | B | ~A | A&B | A|B | A^B |
0 | 0 | 1 | 0 | 0 | 0 |
0 | 1 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 0 | 1 | 1 |
1 | 1 | 0 | 1 | 1 | 0 |
表2-4 位逻辑运算的运算规则
2.移位运算符
Java语言提供了三个移位运算符:左移运算符(<<)、右移运算符(>>)、无符号右移运算符(>>>)
//左移运算符(<<)用来将一个整数的二进制位序列左移若干位。
//移出的高位丢弃,右边添加0
//整数7的二进制序列位:00000000 00000000 00000000 00000111
System.out.println(7<<2); //输出的结果为28 00000000 00000000 00000000 00011100
//右移运算符(>>)用来将一个整数的二进制位序列右移若干位。
//移出的低位丢弃,若为正数,移入的高位添0,若为负数,移入的高位添1。
//整数-192的二进制序列位:11111111 11111111 11111111 0100000000
System.out.println(-192>>>3); //输出的结果为536870888 11111111 11111111 11111111 11101000
//无符号右移运算符(>>>)用来将一个整数的二进制位序列右移若干位。
//它与右移运算符的区别是,不论正数还是负数左边一律移入0。
//整数-192的二进制序列位:11111111 11111111 11111111 0100000000
System.out.println(-192>>>3); //输出的结果为536870888 00011111 11111111 11111111 11101000
2.7.6 运算符的优先级和综合性
图2-6 按优先级从高到低的运算符