一、Java的起源与发展历程
1.1 Java的起源
1.1.1Java的起源可以追溯到20世纪90年代初。
1.1.2Java是James Gosling和他的团队所开发的一种面向对象编程语言。
1.1.3Java的前身为Oak(橡树),因注册商标问题而改名为Java。
1.2 Java的发展历程
图1 - 1 Java的发展历程
1.3 Java语言的优点
Java的优点有:面向对象的、解释型的、分布式的、安全的、可移植的、高性能的、体系结构中立的、安全的、多线程、动态的和平台独立的。
其中最为突出的是面向对象的和平台独立的这两个优点。面向对象的:可以将所有的代码定义在类中,这个些类大多数可以实例化为对象;平台独立的:是指用Java编写的程序编译成字节码之后不依赖与任何平台,只要安装了Java虚拟机,使用Java编写的程序可以在任何平台上运行。
1.4 Java平台和运行机制
1.4.1 Java平台与应用领域
Java平台有三大版本,代表了Java的三个不同领域,分别是:Java标准版,Java企业版,Java微型版。
1.4.1.1 Java标准版(JavaSE):可以用来开发客户端的应用程序,应用程序可以独立运行。
1.4.1.2 Java企业版(JavaEE):可以用来开发服务器端的应用程序,如Java servlet、JavaServer Pages等。
1.4.1.3 Java微型版(JavaME):可以用来开发移动设备上运行的应用程序。
1.4.2 JDK、JRE和JVM
Java源程序必须经过编译才可以运行。编译器是一种将程序源代码转换成可执行格式(字节码、本机代码等)的程序,在使用Java编程之前,必须下载一个Java编译器(即javac)。
使用javac可以将Java源代码编译成字节码,而运行字节码则需要Java虚拟机(Java Virtual Machine,即JVM)。由于常需用到Java核心类库中的类,因此需要下载这些类库,JVM和Java类库一起组成了java运行时环境(Java Runtime Environment,即JRE)。JDK(Java Development Toolkit)是一个包含了Java编译器和其他程序的工具集,是编译和运行Java程序的必备软件。
图 1 - 2 JDK、JRE和JVM的关系
1.4.3 Java字节码与平台独立
Java程序可以在多种操作系统上运行,这里就要提到字节码。在Java编程中,源代码被编译成字节码。字节码只能在Java虚拟机(JVM)上运行, 而JVM可以在众多平台上可用,从而使得Java成为一种跨平台语言,进而实现“编写一次,到处运行”的特点。
图 1 - 3 Java程序的运行机制
二、数据类型与运算符
2.1 Java数据类型
在Java语言中数据类型可分为基本数据类型和引用数据类型两大类。不同的数据有不同的类型,不同的数据类型有不同的数据结构、不同的存储方式,参与的运算也不同。
基本数据类型 | 引用数据类型 | |||
整数类型 | 浮点类型 | 字符类型 | 布尔类型 | class(类) interface(接口) record(记录类型) enum(枚举类型) @interface(注解类型) name[](数组) |
int(整型) short(短整型) long(长整型) byte(字符型) | float(单浮点型) double(双浮点型) | char | boolean |
表2 - 1 Java的数据类型
2.1.1 基本数据类型
整数类型,顾名思义是用来存储整数的,根据数字的大小选择不同的类型;对于带小数点的数字,就需要用浮点类型中的float型或double型;char型可以存储一个字符,如'A'、'9'、'&'等等;boolean型则是包含两种可能状态之一(true或false)。
数据类型 | 占用内存 | 取值范围 | |
字节 | 位数 | ||
int | 4 | 32 | -2^31~2^31-1,即-2 147 483 648~2 147 483 647 |
byte | 1 | 8 | -2^7~2^7-1,即-128~127 |
short | 2 | 16 | -2^15~2^15-1,即-32 768~32 767 |
long | 8 | 64 | -2^63~2^63-1,即-9 223 372 036 854 775 808~9 223 372 036 854 775 807 |
float | 4 | 32 | 1.4*10^-45~3.4*10^38,IEEE754标准 |
double | 8 | 64 | 4.9*10^-432~1.79*10^308,IEEE754标准 |
char | 2 | 16 | 0~65535 |
boolean | 1 | 1 | 只有true和false两个值 |
表 2 - 2 Java的基本数据类型
2.1.2 引用数据类型
类(包括抽象类)是Java语言最重要的引用数据类型,任何Java程序都离不开类的使用。
接口是对类的一种扩展,也是一种引用类型,但不能实例化。广泛应用在类型的多继承和多态性。
枚举是一种特殊的引用类型,用来定义具有确定几个值的类型。
记录类型Java16引入夫的新特性, 主要用来声明用于存储数据的类。
注解类型以结构化的方式为程序元素提供信息,能够被编译器、解释器等外部工具自动处理。
数组是一种特殊的引用类型,只要声明换个创建数组对象,即可像其他引用类型实例一样使用数组。
表 2 - 3 Java引用数据类型
2.2 标识符与语句
2.2.1 Java标识符
在Java中,标识符用来为变量、方法、类型命名。标识符必须以字母、下划线(_)或美元符($)开头,其后可以是字母、下划线、美元符或数字,长度没有限制。标识符区分大小写,name和Name两个标识符是不同的。
2.2.2 Java关键字
关键字是语言事先定义的一组词汇,这些词汇具有特殊的用途,用户不能将它们定义为标识符。以下是Java语言的51个关键词:
goto和const尽管是被保留的关键字,但没有被使用,也不能将其作为标识符使用;true和false是boolean型数据的字面值,null表示引用类型为空。
abstract | assert | boolean | break | byte |
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | short | static | strictfp | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
_(下划线) |
表 2 - 4 Java关键字
除上表中的51个关键字之外,Java还定义了一些受限关键字,如:var用于类型占位符,yield用于switch-case中返回一个值,recond用于声明一个记录类型,在模块中使用的require、exports等受限关键字。
2.2.3 变量、赋值、语句
变量是程序运行中其值可以改变的量,一个变量通常由数据类型、变量名和变量值三个要素组成。变量声明的一般格式为:
type varName[ = value][,varName2 = [ value2] ···];
其中,type为变量类型,可以是基本类型,也可以是引用类型;varName为变量名,变量名必须是合法的标识符;value为变量值。 以下声明几个不同类型的变量作为参考。
int age;
double d1,d2;
char ch1,ch2;
使用赋值运算符"="可以给变量进行赋值,一般称之为变量的初始化。以下几条赋值语句作为参考。
age = 21;
ch1 = 'A';
d1 = d2 = 1.679; //可以一次给多个变量赋值
boolean b = true; //也可以在声明变量的同时进行赋值
程序是由一系列的指令组成,这些指令称之为语句。在Java当中有简单的语句(如:声明语句、赋值语句),也有流程控制语句(如:if、while、for)等。语句的结束以 ;(分号)结束。
语句可以集中放在一个块中。根据定义,块(block)是花括号内的一系列编程元素。
int y; //变量声明语句
y = x + 5; //变量赋值语句
y = x + 1; y = x + 2; //多条语句可以写在同一行中,但会降低代码的可读性
//部分表达式在末尾加上分号,即可成为语句。如:
i++ //表达式
i++; //语句
2.3 基本数据类型
2.3.1 整数类型
Java提供了四种整数类型:byte(字符型)、short(短整型)、int(整型)和long(长整型)。这些整数类型都有符号数,可以为正值或负值。每种类型的整数在内存中的占位不同,能够表示的数值范围也不同。详见表2 - 2。
Java的整数类型字面值有以下四种表示形式:
(1)二进制形式,以0b或0B开头的数,如0B00101010表示十进制数 42。
(2)八进制形式,以0开头的数,如0124表示十进制数 84,-012表示十进制数 -10。
(3)十进制形式,如0、257、-365。
(4)十六进制形式,以0x或0X开头的整数,如0x124表示十进制数的 292。
2.3.2 浮点类型
浮点类型的数就是数学上通常说的实数,Java中有两种浮点类型数据:float型和double型。这两种类型的数据在内存中所占的位数不同,通常将float型称为单精度浮点型,将double型称为双精度浮点型。它们符合IEEE-754的标准。
浮点类型字面值有两种表示方法:
(1)十进制数形式,由数字和小数点组成,且必须有小数点,如0.256、.49、82. 、2.0等。
(2)科学计数法形式,如256e3、256e-3,它们分别表示256*10^3 和256*10^-3。e的前面必须有数字,e后面的指数必须为整数。
2.3.3 字符类型
字符是程序中可以出现的任何单个符号。字符类型的字面值用单引号将字符括起来。如:'a'、'@'、'我' 等等。对于不能直接用单引号括起来的字符则需要使用转义序列表示,表示方法是用反斜杠(\)表示转义。
转义字符 | 说明 | 转义字符 | 说明 |
\' | 单引号字符 | \b | 退格 |
\" | 双引号字符 | \r | 回车 |
\\ | 反斜杠字符 | \n | 换行 |
\f | 换页 | \t | 水平制表符 |
表2 - 5 Java常见转义序列
2.3.4 布尔类型
布尔类型数据用来表示逻辑真或逻辑假,布尔类型的常量只有true和false两个值。布尔类型变量声明使用boolean关键字声明,所有关系表达式的返回值都是布尔类型的数据。如:7>4的结果为true;5<3的结果为false。
2.4 字符串类型
程序中经常用到字符串。字符串是字符序列,不属于基本数据类型,是一种引用类型。Java字符串是通过String类实现的。可以使用String类声明和创建一个字符串对象,可以通过双引号定界符来创建一个字符串字面值。如:
String a = "Java is so cool"
对于较长的字符串,可以使用加号运算符(+)将两个字符串进行连接,如:
String a = "Hello" + ",World."
还可以将一个字符串和一个基本类型或是另一个对象连接在一起,如:
int age = 20;
System.out.println("我的年龄是:" + age + "岁");
2.5 数据类型转换
Java语言是强类型语言,即每个常量、变量、表达式的值都有固定的类型,而且每种类型都是严格定义的。在Java编译阶段,编译器要对类型进行严格的检查,任何不匹配的类型都不能通过编译器,因此就需要进行数据类型转换。
在Java中,基本数据类型的转换分为自动类型转换和强制类型转换。
2.5.1 自动类型转换
自动类型转换也称之为加宽转换,指将具有较少位数的数据类型转换为具有较多位数的数据类型,如:
byte a = 123;
int b = a; //字节型数据a自动转换为整型
允许自动转换的类型有:
从 byte 到 short、int、long、float 或 double; |
从 short 到 int、long、float 或 double; |
从 char 到 int、long、float 或 double; |
从 int 到 long、float 或 double; |
从 long 到 float 或 double; |
从 float 到 double。 |
表 2 - 6 自动转换类型
图 2 - 1 基本类型的自动转换
2.5.2 强制类型转换
强制类型转换又称为缩窄转换,是将位数较多的数据类型转换为位数较少的数据类型,如:
double d = 100.5;
byte b = (byte)d; //将double型值强制转换成byte型值
一般来说,需要继续强制转换的类型有:
从 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 - 7 强制转换类型
2.5.3 表达式类型自动提升
除了赋值可能发生类型转换外,在含有变量的表达式中,也有类型转换的问题,如:
byte a = 10;
byte b = 20;
byte c = a + b; //编译错误,提示Required type:byte,Provided:int
byte c = (byte)(a + b); //编译正确
int a + b;
2.6 运算符
运算符和表达式是Java程序的基本组成要素。把表示各种不同运算的符号成为运算符,参与运算的各种数据成为操作数。运算符包括:算术运算符、关系运算符、逻辑运算符、赋值运算符和位运算符五种。
表达式是由运算符和操作数按一定语法规则组成的符号序列。
2.6.1 算术运算符
算术运算符一般用于对整数型和浮点型数运算。算术运算符有以下几种:
一元运算符 | 二元运算符 |
+(正) | +(加) |
-(负) | -(减) |
++(自增) | *(乘) |
--(自减) | /(除) |
%(取余数) |
表 2 - 8 算术运算符类型
自增(++)和自减(--)运算符主要用于对变量的操作,其中“++”表示加1,“--”表示减1。它们可以使用在变量的前面或后面,若放在变量前,则表示先给变量进行加/减 1 后再使用该变量;若放在变量后,则表示先使用该变量,再给变量进行加/减 1 的操作。例:
int b = 5;
a = b++; //结果:y = 5,x = 6
a = ++b; //结果:y = 6,x = 6
a = b--; //结果:y = 5,x = 4
a = --b //结果:y = 4,x = 4
自增和自减运算也可用于浮点型变量,如:
double d = 3.14;
d++; //结果:d = 4.14;
2.6.2 关系运算符
关系运算符也称比较运算符,用来比较两个值的大小是否相等。Java中有6中关系运算符,如表2 - 9所示。
运算符 | 含义 | 运算符 | 含义 |
> | 大于 | <= | 小于或等于 |
>= | 大于或等于 | == | 等于 |
< | 小于 | != | 不等于 |
表 2 - 9 关系运算符类型
关系运算符一般用来构成条件表达式,比较的结果返回true或false。如:
int x = 9;
int y = 32;
char c = 'B';
System.out.println(x < y); //输出true
System.out.println(c >= 'A'); //输出true
2.6.3 逻辑运算符
逻辑运算符的运算对象只能是布尔类型的数据,并且运算结果也是布尔类型数据。逻辑运算符有以下几种:
逻辑与(&) | 逻辑异或(^) |
逻辑或(|) | 短路与(&&) |
逻辑非(!) | 短路或(||) |
表2 - 10 逻辑运算符类型
假定A、B是两个布尔类型数据,则逻辑运算的规则如表2-11所示。
A | B | A&B | A|B | !A | A^B | A&&B | A||B |
false | false | false | false | true | false | false | false |
false | true | false | true | true | true | false | true |
true | false | false | true | false | true | false | true |
true | true | true | true | false | false | true | true |
表 2 - 11 逻辑运算的运算规则
对于短路运算符,当使用"&&"进行“与”运算时,若第一个(左面)操作数的值为false时,就可以判断整个表达式的值为false,无需继续求解第二个(右面)表达式的值。当使用"||"进行“或”运算时,若第一个(左面)操作数的值为true时,就可以判断整个表达式的值为true,无需继续求解第二个(右面)表达式的值。
对于逻辑异或(^),在使用时,当两个操作数一个是true,一个是false时,结果为true;否则结果为false。简单来说就是:有true出true,没true出false。
2.6.4 赋值运算符
赋值运算符用来为变量指定新值。赋值运算符主要有两类,一类是使用等号(=)进行赋值,把一个表达式的值赋给一个变量或对象;另一类是复合的赋值运算。
//1.赋值运算符
varName = expression; //赋值运算符的一般格式
int x = 10;
int y = x + 10;
//赋值运算必须是类型兼容的,即左边的变量必须能够接收右边的表达式的值,否则会产生编译错误,如:
int i = 3.14;
//使用(=)可以给对象赋值,这称为 引用赋值 ,指将右边对象的引用值(地址)赋给左边的变量,如:
Student s1 = new Student();
Student s2 = s1;
//2.复合赋值运算符:在赋值运算符(=)前加上其他运算符,即构成复合赋值运算符。
varName op = expression;//复合赋值运算符的一般格式;这里的op为运算符,含义是将变量varName的值与expression的值做op运算,结果赋给varName
//在复合赋值运算符中,如果等号右侧是一个表达式,表达式将作为一个整体参加运算。如:
int a = 5;
a += 5 * ++a / 5 + 2;
System.out.println(a);
//上述代码等价于下面的代码:
a = a + (5 * ++a / 5 + 2);
复合赋值运算符有11个,设a=15,b=3,则复合赋值运算符及其使用方法如表2-12所示。
扩展赋值运算符 | 表达式 | 等价表达式 | 结果 |
+= | 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 - 12 扩展的赋值运算符
2.6.5 位运算符
位运算是在整数的二进制位上进行的运算。在Java语言中,整数是用二进制的补码表示的。位运算有两类:位逻辑运算和移位运算。位运算符只能用于整型数据,包括byte、short、int、long和char 类型。
位逻辑运算包括按位取反(~)、按位与(&)、按位或(|)和按位异或(^)。
移位运算包括左移(<<)、右移(>>)和按位无符号右移(>>>)。
设a = 10,b = 3时,则位运算符及其使用方法如表2-13所示。
运算符 | 功能 | 示例 | 结果 |
~ | 按位取反 | ~a | -11 |
& | 按位与 | a & b | 2 |
| | 按位或 | a | b | 11 |
^ | 按位异或 | a ^ b | 9 |
<< | 左移 | a << b | 80 |
>> | 右移 | a >> b | 1 |
>>> | 按位无符号右移 | a >>> b | 1 |
表 2 - 13 位运算符
2.6.5.1 位逻辑运算符
位逻辑运算符对一个整数的二进制位进行运算,设A、B表示操作数的一位。位逻辑运算的规则如表2-14所示。
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 - 14 位逻辑运算的规则
2.6.5.2 移位运算符
Java 语言提供了3个移位运算符:左移运算符(<<)、右移运算符(>>)和无符号右移运算符(>>>)。
左移运算符(<<)用来将一个整数的二进制位序列左移若干位。移出的高位丢弃,右边添0。
右移运算符(>>)用来将一个整数的二进制位序列右移若干位。移出的低位丢弃。若为正数,移入的高位添0,若为负数,移入的高位添1。
无符号右移运算符(>>>)也是将一个整数的二进制位序列右移若干位。它与右移运算符的区别是,不论正数还是负数左边一律移入0。
值得注意的是,位逻辑运算符和移位运算符都只能用于整型或字符型,不能用于浮点型数据。
2.6.6 运算符的优先级和结合性
运算优先级是指在一个表达式中出现多个运算符又没有用括号分隔时,先运算哪个后算哪个。常说的“先算乘除后算加减”指的就是运算符优先级问题。
优先级 | 运算符 | 名称 | 结合性 |
1 | ++ | 自增 | 右结合 |
-- | 自减 | ||
+、- | 正、负 | ||
~ | 按位取反 | ||
! | 逻辑非 | ||
(case)、new | 类型转换、创建对象 | ||
->、:: | 箭头和方法引用 | 左结合 | |
. | 字段访问和方法调用 | ||
2 | *、/、% | 乘、除、求余 | 左结合 |
3 | +、- | 加、减 | 左结合 |
+ | 字符串连接 | ||
4 | <<、>>、>>> | 左移、右移、无符号右移 | 左结合 |
5 | <、<=、>、>=、instanceof | 小于、小于或等于、大于、大于或等于、实例运算符 | 左结合 |
6 | ==、!= | 相等、不相等 | 左结合 |
7 | & | 按位与、逻辑与 | 左结合 |
8 | ^ | 按位异或、逻辑异或 | 左结合 |
9 | | | 按位或、逻辑或 | 左结合 |
10 | && | 逻辑与(短路) | 左结合 |
11 | || | 逻辑或(短路) | 左结合 |
12 | ?: | 条件运算符 | 右结合 |
13 | = | 赋值 | 右结合 |
+=、-=、*=、/=、&=、&=、|=、^=、<<=、>>=、>>>= | 复合赋值 | 右结合 |
表 2 - 15 按优先级从高到低的运算符