Java基础语法
Java关键字
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 | null | package | private | protected |
public | return | short | static | strictfp |
super | switch | synchronized | this | throw |
throws | transient | try | void | volatile |
while |
Java标识符
所有Java组件都需要名称。 用于类,变量和方法的名称称为标识符。
在Java中,标识符的命名有几点要记住。 它们如下 -
- 所有标识符都应以字母(
A
到Z
或a
到z
),货币字符($
)或下划线(_
)开头。 - 在第一个字符之后,标识符可以是任何字符组合。
- 关键字不能用作标识符。
- 标识符区分大小写。
- 合法标识符的示例:
age
,$salary
,_value
,__1_value
。 - 非法标识符的示例:
123abc
,-salary
。
注 - Java使用的是uicode编码,是可以用中文命名的,不过笔者建议别用中文。
Java程序规范
关于Java程序,请务必牢记以下几点。
- 区分大小写 - Java区分大小写,因此标识符
Hello
和hello
在Java中具有不同的含义。 - 类名 - 对于所有类名,第一个字母应为大写。 如果使用多个单词来形成类的名称,则每个内部单词的第一个字母应为大写。
示例:class MyFirstJavaClass
- 方法名称 - 所有方法名称都应以小写字母开头。如果使用多个单词来形成方法的名称,那么每个内部单词的第一个字母应该是大写字母。
示例:public void myMethodName()
- 程序文件名 - 程序文件的名称应与类名完全匹配。保存文件时,应使用类名保存它(记住Java区分大小写)并在名称的末尾使用扩展名称:
.java
(如果文件名和类名不匹配,则程序将无法编译))。但请注意,如果代码文件中没有public class
,则文件名可能与类名不同。在代码文件中也没有强制要求必须有public class
。
示例:假设MyFirstJavaProgram
是类名,那么该文件应保存为:MyFirstJavaProgram.java。 public static void main(String args[])
− Java程序处理从main()
方法开始,该方法是每个Java程序的必需部分。
Hello,World!
1 |
|
注意,可能在使用javac
报错:
1 |
|
Java枚举
枚举是在Java 5.0中引入的。 枚举将变量限制为仅具有少数预定义值之一。此枚举列表中的值称为枚举。
通过使用枚举,可以减少代码中的错误数量。
例如,在新鲜果汁店中,可将玻璃杯大小限制为:小杯,中杯和大杯。 这将确保它不允许购买除了小杯,中杯或大杯之外的玻璃杯。
示例代码:
1 |
|
编译并执行上面示例代码,得到以下结果:
1 |
|
注 - 枚举可以单独声明或在类中声明。 方法,变量,构造函数也可以在枚举内定义。
Java修饰符
修饰符是一种添加到定义以更改其含义的关键字。Java语言有各种各样的修饰符,包括以下两种:
- Java访问修饰符 - 例如:
private
,protected
,public
等。 - Java非访问修饰符 - 例如:
static
,final
等。
要使用修饰符,请在类,方法或变量的定义中包含修饰符关键字。 修饰符位于语句之前,如下例所示:
1 |
|
访问控制修饰符
Java提供了许多访问修饰符来设置类,变量,方法和构造函数的访问级别。 四个访问级别是:
private
: 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)default
(即缺省,什么也不写,不使用任何关键字): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。protected
: 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)。public
: 对所有类可见。使用对象:类、接口、变量、方法
强制执行以下继承方法规则:
- 在超类中声明为
public
的方法也必须在所有子类中都是public
。 - 在超类中声明为
protected
的方法必须在子类中也要声明为:protected
或public
; 不能声明为:private
。 - 声明为
private
的方法根本不能被继承,因此没有规则。
非访问修饰符
Java提供了许多非访问修饰符来实现许多其他功能。
- 用于创建类方法和变量的
static
修饰符。 - 用于完成类,方法和变量的实现的
final
修饰符。 - 用于创建抽象类和方法的
abstract
修饰符。 synchronized
和volatile
修饰符,用于线程。
static修饰符
静态变量
static
关键字用于创建独立于类实例的变量。无论类的实例数有多少个,都只存在一个静态变量副本。静态变量也称为类变量。局部变量不能声明为static
。
静态方法
static
关键字用于创建独立于类实例的方法。
静态方法不能使用作为类的对象的实例变量,静态方法也叫作类方法。静态方法从参数中获取所有数据并从这些参数计算某些内容,而不引用变量。可以使用类名后跟一个点(.
)以及变量或方法的名称来访问类变量或方法。
static
修饰符用于创建类方法和变量,如下例所示:
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
final修饰符
final变量
final变量只能显式地初始化一次,声明为final
的引用变量永远不能重新分配以引用不同的对象。但是,可以更改对象内的数据。 因此,可以更改对象的状态,但不能更改引用。
对于变量,final
修饰符通常与static
一起使用,以使常量成为类变量。
1 |
|
final方法
任何子类都不能覆盖final
方法。 如前所述,final
修饰符可防止在子类中修改方法。
声明final
方法的主要目的是不让其它人改变方法的内容。
可以在类声明中使用final
修饰符声明方法,如下例所示:
1 |
|
final类
使用声明为final
的类的主要目的是防止类被子类化。 如果一个类被标记为final
,那么这个类不能被其它类继承。
示例
1 |
|
abstract修饰符
抽象类
抽象(abstract
)类不能实例化。如果一个类声明为抽象(abstract
),那么唯一的目的是扩展该类。
一个类不能是同时是abstract
和final
(因为final
类不能被扩展)。 如果一个类包含抽象方法,那么该类应该被声明为abstract
。 否则,将抛出编译错误。
抽象类可以包含抽象方法以及普通方法。
1 |
|
抽象方法
抽象方法是在没有任何实现的情况下声明的方法。 方法体(实现)由子类提供。 抽象方法永远不会是最终的或严格的。
扩展抽象类的任何类都必须实现超类的所有抽象方法,除非子类也是抽象类。
如果一个类包含一个或多个抽象方法,那么该类必须声明为abstract。 抽象类不需要包含抽象方法。
抽象方法以分号结尾。 示例:public abstract sample();
1 |
|
synchronized修饰符
synchronized
关键字用于指示一次只能访问一个方法的方法。synchronized
修饰符可以应用于四个访问级别修饰符中的任何一个。
1 |
|
transient修饰符
实例变量标记为transient
,表示JVM在序列化包含它的对象时跳过特定变量。
此修饰符包含在创建变量的语句中,位于变量的类或数据类型之前。
1 |
|
volatile修饰符
volatile
修饰符用于让JVM知道访问变量的线程必须始终将其自己的变量私有副本与内存中的主副本合并。
访问volatile
变量会同步主内存中变量的所有缓存复制。 volatile
只能应用于实例变量,类型为private
。 volatile
对象引用可以为null
。
1 |
|
通常,在一个线程(使用Runnable
开始的线程)中调用run()
,并从另一个线程调用stop()
。 如果在第1
行中使用了active
的缓存值,那么当在第2
行中将active
设置为false
时,循环可能不会停止。
Java变量
变量提供了程序可以操作的命名存储。 Java中的每个变量都有一个类型,它决定了变量内存的大小和布局; 可以存储在该存储器中的值的范围; 以及可以应用于变量的操作集。
变量需要先声明才能使用,以下是变量声明的基本形式 -
1 |
|
这里data type
是Java的数据类型之一,variable
是变量的名称。要声明具有相同类型的多个变量,可以使用逗号分隔列表。
以下是Java中变量声明和初始化的示例 -
1 |
|
Java中有三种变量 -
- 局部变量
- 实例变量
- 类/静态变量
局部变量
- 局部变量一般在方法,构造函数或块中声明。
- 程序进入方法,构造函数或块时会创建局部变量,并且一旦退出方法,构造函数或块,变量就会销毁。
- 访问修饰符不能用于局部变量。
- 局部变量仅在声明的方法,构造函数或块中可见。
- 局部变量在内部实现堆栈级别。
- 局部变量没有默认值,因此应声明局部变量后,在第一次使用之前为它分配初始值。
在这里,age
是一个局部变量。 这是在dogAge()
方法中定义的,它的范围仅限于此方法。
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
下面示例中使用变量 age
,但不初始化它,因此在编译时会出错。
1 |
|
执行上面示例代码,得到以下结果(出错):
1 |
|
实例变量
- 实例变量在类中声明,但在方法,构造函数或块之外。
- 为堆中的对象分配空间时,将为每个实例变量值创建一个槽。
- 使用关键字
new
创建对象时会创建实例变量,并在销毁对象时销毁实例变量。 - 实例变量包含由多个方法,构造函数或块引用的值,或者在整个类中存在的对象状态的基本部分。
- 实例变量可以在使用之前或之后在类级别中声明。
- 可以为实例变量给出访问修饰符。
- 实例变量对于类中的所有方法,构造函数和块都是可见的。 通常,建议将这些变量设为私有(访问级别)。 但是,可以使用访问修饰符为这些变量提供子类的可见性。
- 实例变量具有默认值。 对于数字,默认值为
0
,对于布尔值,它为false
,对于对象引用,它为null
。 可以在声明期间或构造函数中指定值。 - 可以通过调用类中的变量名来直接访问实例变量。 但是,在静态方法中(当实例变量具有可访问性时),应使用完全限定名称调用它们,如:
ObjectReference.VariableName
。
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
类/静态变量
- 类变量(也称为静态变量)在类中使用
static
关键字声明,但在方法,构造函数或块之外。 - 每个类只有一个每个类变量的副本,无论从中创建多少个对象。
- 除了声明为常量之外,很少使用静态变量。常量是声明为
public/private
,final
和static
的变量。常量的初始值不能更改。 - 静态变量存储在静态存储器中。 除了声明的
final
之外,很少使用静态变量,并将其用作公共或私有常量。 - 程序启动时会创建静态变量,程序停止时会销毁静态变量。
- 可见性类似于实例变量。 但是,大多数静态变量都是公共的,因为它们必须可供该类用户使用。
- 默认值与实例变量相同。 对于数字,默认值为
0
; 对于布尔类型来说,默认值为false
; 对于对象引用,默认值为null
。 可以在声明期间或构造函数中指定值。 此外,可以在特殊的静态初始化程序块中分配值。 - 可以通过使用类名
ClassName.VariableName
调用来访问静态变量。 - 将类变量声明为
public static final
时,变量名(常量)都是大写的。 如果静态变量不是public
和final
,则命名语法与实例和局部变量命名规则相同。
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
注 - 如果从外部类访问变量,则应作为:
Employee.DEPARTMENT
。
Java基本数据类型
变量是用于存储值的保留内存位置。当创建变量时,它会在内存中保留一些空间。
根据变量的数据类型,操作系统分配内存并决定可以存储在保留内存中的内容。 因此,通过为变量分配不同的数据类型,可以在这些变量中存储整数,小数或字符。
Java中有两种数据类型 -
- 原始数据类型
- 引用/对象数据类型
原始数据类型
Java支持八种原始数据类型。 原始数据类型由语言预定义,并由关键字命名。下面来详细了解和学习这八种原始数据类型。
类型 | 描述 | 值范围 | 默认值 | 示例 |
---|---|---|---|---|
byte | 表示8 位有符号二进制补码整数 |
-128 (-2^7) - 127 (2^7 -1) |
0 |
byte a = 100, byte b = -50 |
short | 表示16 位有符号二进制补码整数 |
-2^15 -2^15 -1 |
0 |
short s = 10000, short r = -20000 |
int | 表示32 位有符号二进制补码整数 |
-2^31 -2^31 -1 |
0 |
int a = 100000, int b = -200000 |
long | 表示64 位带符号的二进制补码整数 |
-2^63 -2^63 -1 |
0L |
long a = 100000L, long b = -200000L |
float | 表示单精度32 位IEEE 754浮点数 |
- | 0.0f |
float f1 = 234.5f |
double | 表示双精度64 位IEEE 754浮点数 |
- | 0.0d |
double d1 = 123.4 |
boolean | 表示一个比特位的信息 | true /false |
false |
boolean one = true |
char | 表示单个16位Unicode字符 | \u0000 -\uffff |
- | char letterA = 'A' |
引用数据类型
- 使用类中已定义构造函数创建引用变量。 它们用于访问对象。 声明这些变量属于无法更改的特定类型。 例如,
Employee
,Dog
类等。 - 类对象和各种类型的数组变量属于引用数据类型。
- 任何引用变量的默认值为
null
。 - 引用变量可用于引用声明类型的任何对象或任何兼容类型。
- 示例:
Dog dog = new Dog("旺财");
Java文字
文字是固定值的源代码表示。它们直接在代码中表示,无需任何计算。可以将文字分配给任何基本类型变量。 例如 -
1 |
|
byte
,int
,long
和short
也可以用十进制(基数为10
),十六进制(基数16
)或八进制(基数8
)数字表示。
前缀0b
用于表示二进制,前缀0
用于表示八进制,前缀0x
表示使用这些数字系统进行文字时的十六进制。 例如 -
1 |
|
Java中的字符串文字通过在一对双引号之间包含一系列字符来指定,就像它们在大多数其他编程语言中一样。 字符串文字的例子是 -
1 |
|
字符串和字符类型的文字可以包含任何Unicode字符。 例如 -
1 |
|
Java语言也支持String
和char
文字的几个特殊转义序列。它们是 -
符号 | 代表的字符 |
---|---|
\n |
换行符(0x0a) |
\r |
回车(0x0d) |
\f |
换页(0x0c) |
\b |
退格(0x08) |
\s |
空格(0x20) |
\t |
制表符 |
\" |
双引号 |
\' |
单引号 |
\\ |
反斜线 |
\ddd |
八进制字符(ddd) |
\uxxxx |
十六进制UNICODE字符(xxxx) |
Java数组
数组是存储多个相同类型变量的对象。 但是,数组本身是堆上的对象。
Java提供了一种叫作数组的数据结构,它是一种用来存储相同类型元素的固定大小顺序集合。 数组用于存储数据集合,但也可以将数组视为相同类型的变量集合。
声明一个数组变量(如:numbers
)并使用numbers[0]
,numbers[1]
和...
,numbers[99]
来表示单个变量,例如number0
,number1
,...
和number99
,而不是单独地声明各个变量。
本教程介绍如何声明数组变量,创建数组和索引访问数组。
声明数组变量
要在程序中使用数组,需要先声明一个变量以引用该数组,并且要指定该变量的数组类型。 以下是声明数组变量的语法 -
1 |
|
注 - 格式:
dataType [] arrayRefVar
是推荐方式。 格式:dataType arrayRefVar []
来自C/C++语言,可在Java中采用以适应C/C++程序员。
以下代码片段是此语法的示例 -
1 |
|
创建数组
可以使用new
运算符来创建数组,如以下语法 -
1 |
|
上面语句做了两件事 -
- 它使用
new dataType[arraySize]
来创建了一个数组。 - 它将新创建的数组的引用分配给变量
arrayRefVar
。
声明一个数组变量,创建一个数组,并将该数组的引用分配给变量,可以在一个语句中完成,如下所示 -
1 |
|
或者,可以按如下方式创建数组 -
1 |
|
通过索引访问数组元素。 数组索引值从0
开始; 也就是说,它们从0
开始到arrayRefVar.length - 1
。
下面语句中声明了一个数组变量myList
,它创建了一个包含10
个double
类型元素的数组,并将数组变量的引用分配给myList
-
1 |
|
下表表示数组myList
。 这里,myList
数组中包含十个double
值,索引从0
到9
。
数组下标索引 | 元素的值 |
---|---|
myList[0] | 5.6 |
myList[1] | 4.5 |
myList[2] | 3.3 |
myList[3] | 13.2 |
myList[4] | 4.0 |
myList[5] | 34.33 |
myList[6] | 34.0 |
myList[7] | 45.45 |
myList[8] | 99.993 |
myList[9] | 11123 |
处理数组
处理数组元素时,经常使用for
循环或foreach
循环,因为数组中的所有元素都是相同的类型,并且数组的大小是已知的。
这是一个完整的示例,演示了如何创建,初始化和处理数组 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
foreach循环
JDK 1.5引入了foreach
循环或增强for
循环,它能够在不使用索引变量的情况下顺序遍历整个数组。
以下代码演示如何遍历数组myList
中的所有元素 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
将数组传递给方法
就像将原始类型值传递给方法一样,也可以将数组传递给方法。 例如,以下printArray()
方法用来打印int
数组中的元素 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
从方法返回数组
方法可以返回数组。 例如,以下方法返回一个与给定参数数组相反的数组 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
Arrays类
java.util.Arrays
类包含各种静态方法,用于排序和搜索数组,比较数组和填充数组元素。 对于所有基本类型,这些方法都会重载。
方法 | 描述 |
---|---|
public static int binarySearch(Object[] a, Object key) |
使用二进制搜索算法搜索指定的Object(Byte,Int,double等)数组以获取指定值。 必须在进行此调用之前对数组进行排序。 如果搜索关键字包含在列表中,则返回搜索关键字的索引; 否则,它返回( -(插入点 + 1))。 |
public static boolean equals(long[] a, long[] a2) |
如果两个指定的long 数组相等,则返回true 。 如果两个数组包含相同数量的元素,则两个数组被认为是相等的,并且两个数组中的所有相应元素对相等。如果两个数组相等,则返回true 。 所有其他原始数据类型(Byte,Short,Int等)可以使用相同的方法。 |
public static void fill(int[] a, int val) |
将指定的int 值分配给指定的int 数组的每个元素。所有其他原始数据类型(Byte,Short,Int等)可以使用相同的方法。 |
public static void sort(Object[] a) |
根据元素的自然顺序,将指定的对象数组按升序排序。 所有其他原始数据类型(Byte,Short,Int等)可以使用相同的方法。 |
Java基本运算符
Java提供了一组丰富的操作符来操作变量。 我们可以将所有Java运算符划分为以下几个分类 -
- 算术运算符
- 关系运算符
- 按位运算符
- 逻辑运算符
- 赋值运算符
- 其他运算符
算术运算符
算术运算符在数学表达式中的使用方式与在代数中使用的方式相同。下表列出了算术运算符的使用示例 -
假设整数类型变量A
的值为:10
,变量B
的值为:20
,则 -
运算符 | 描述 | 示例 |
---|---|---|
+ |
加法运算符,第一个操作数加上第二个数操作数 | A + B 结果为:30 |
- |
减法运算符,从第一个操作数减去第二个操作数 | A - B 结果为:-10 |
* |
两个操作数相乘 | A * B 结果为:200 |
/ |
左操作数除以右操作数返回模值 | B / A 结果为:2 |
% |
左操作数除以右操作数返回余数 | B / A 结果为:0 |
++ |
将操作数的值增加1 |
A++ ,则A 的值为:11 |
-- |
将操作数的值减1 |
A-- ,则A 的值为:9 |
算术运算符示例代码 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
关系运算符
Java语言支持以下关系运算符。假设变量A
的值是10
,变量B
的值是20
,则 -
运算符 | 描述 | 示例 |
---|---|---|
== |
等于运算符,检查两个操作数的值是否相等,如果相等,则条件变为真。 | A==B 结果为假。 |
!= |
不等于运算符,检查两个操作数的值是否不相等,如果不相等,则条件变为真。 | A!=B 结果为真。 |
> |
大于运算符,检查左操作数的值是否大于右操作数的值,如果大于,则条件变为真。 | A>B 结果为假。 |
< |
小于运算符,检查左操作数的值是否小于右操作数的值,如果小于,则条件变为真。 | A<B 结果为真。 |
>= |
大于或等于运算符,检查左操作数的值是否大于等于右操作数的值,如果大于或等于,则条件变为真。 | A>=B 结果为假。 |
<= |
小于或等于运算符,检查左操作数的值是否小于或等于右操作数的值,如果小于或等于,则条件变为真。 | A<=B 结果为真。 |
Java关系运算符示例代码如下 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
按位运算符
Java定义了几个按位运算符,可以应用于整数类型, 如:long
,int
,short
,char
和byte
。按位运算符处理位并执行逐位运算。 假设a = 60
且b = 13
; 采用二进制格式,它们将如下 -
1 |
|
下面的表中列出了按位运算符,假设整数变量A=60
,变量B=13
,那么 -
运算符 | 描述 | 示例 |
---|---|---|
& |
二进制AND运算符,如果存在于两个操作数中,则它会将结果复制到结果中。 | A & B 的结果为:12 ,也就是:0000 1100 |
Ι | 二进制OR运算符,如果存在于任一操作数中,则复制一位。 | A Ι B 的结果为:61 ,也就是:0011 1101 |
^ |
二进制异或运算符,如果在一个操作数中设置但不在两个操作数中设置,则复制该位。 | A ^ B 的结果为:49 ,也就是:0011 0001 |
~ |
二元一元补充运算符是一元的,具有“翻转”位的效果。 | ~A 的结果为:-61 ,也就是:1100 0011 |
<< |
二进制左移运算符,左操作数值向左移动右操作数指定的位数。 | A << 2 的结果为:240 ,也就是:1111 0000 |
>> |
二进制右移运算符,左操作数值向右移动右操作数指定的位数。 | A >> 2 的结果为:15 ,也就是:1111 |
>>> |
右移零填充运算符。 左操作数值向右移动右操作数指定的位数,移位值用零填充。 | A >>>2 的结果为:15 ,也就是:0000 1111 |
按位运算符示例代码如下 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
逻辑运算符
下表列出了逻辑运算符 -
假设布尔变量A
的值为:true
,变量B
的值为:false
,则 -
运算符 | 描述 | 示例 |
---|---|---|
&& |
逻辑AND运算符。 如果两个操作数都不为零,则条件成立。 | (A && B) 结果为:false |
ΙΙ |
逻辑OR运算符。 如果两个操作数中的任何一个非零,则条件变为真。 | (A ΙΙ B)结果为:true |
! |
逻辑非运算符。用于反转其操作数的逻辑状态。 如果条件为真,则口逻辑NOT运算符将为false 。 |
!(A && B) 结果为:true |
逻辑运算符示例代码如下 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
赋值运算符
以下是Java语言支持的赋值运算符 -
运算符 | 描述 | 示例 |
---|---|---|
= |
简单赋值运算符。 将右侧操作数的值分配给左侧操作数。 | C = A + B 将A + B 的值分配给C 。 |
+= |
相加与赋值运算符。 它将右操作数相加到左操作数并将结果分配给左操作数。 | C += A 等于C = C + A 。 |
-= |
减去与赋值运算符。 它从左操作数中减去右操作数,并将结果赋给左操作数。 | C -= A 等于C = C - A 。 |
*= |
乘以与赋值运算符。 它将右操作数与左操作数相乘,并将结果赋给左操作数。 | C *= A 等于C = C * A 。 |
/= |
除以与赋值运算符。 它将左操作数除以右操作数,并将结果赋给左操作数。 | C /= A 等于C = C / A 。 |
%= |
模数与赋值运算符。 它使用两个操作数来计算获取模数,并将结果赋给左操作数。 | C %= A 等于C = C % A 。 |
<<= |
左移与赋值运算符。 | C <<= 2 与C = C << 2 相同 |
>>= |
右移与赋值运算符。 | C >>= 2 与C = C >> 2 相同 |
&= |
按位与赋值运算符。 | C &= 2 与C = C & 2 相同 |
^= |
按位异或和赋值运算符。 | C ^= 2 与C = C ^ 2 相同 |
Ι= |
按位包含或与赋值运算符。 | C Ι= 2与C = C Ι=2相同 |
赋值运算符示例代码如下 -
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
其它运算符
Java语言支持的其他运算符很少。
条件运算符(?:)
条件运算符也称为三元运算符。 此运算符由三个操作数组成,用于计算布尔表达式。 运算符的目标是确定应将哪个值赋给变量。 运算符写成 -
1 |
|
下面是一段示例代码:
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
instanceof运算符
此运算符仅用于对象引用变量。 运算符检查对象是否属于特定类型(类类型或接口类型)。 instanceof
运算符写成 -
1 |
|
如果操作符左侧的变量引用的对象是右侧的类/接口类型,则结果为真。 以下是一个例子 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
如果要比较的对象与右侧类型兼容,则此运算符仍将返回true
。 以下是另一个例子 -
1 |
|
执行上在示例代码,得到以下结果:
1 |
|
Java循环控制
在程序执行过程中,存在需要多次执行代码块的情况。 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。
编程语言提供各种控制结构,允许更复杂的执行路径。
三大循环
Java编程语言提供以下类型的循环来处理循环要求 -
编号 | 循环 | 描述 |
---|---|---|
1 | while循环 | 在给定条件为真时重复语句或语句组,它在执行循环体之前测试条件。 |
2 | for循环 | 多次执行一系列语句,并缩写管理循环变量的代码。 |
3 | do…while循环 | 像while 语句一样,但是它在末端测试循环体的条件。 |
while循环
只要给定条件为真,Java编程语言中的while
循环语句就会重复执行目标语句。
语法
while
循环的语法是 -
1 |
|
这里,语句可以是单个语句或语句块。 条件(boolean_expression
)可以是任何表达式,true
是任何非零值。
执行时,如果boolean_expression
结果为true
,则执行循环内的操作。只要表达式结果为true
,它将继续执行。
示例1. Java while循环
这是一个简单的java while循环示例,用于打印5
到10
之间的数字。
1 |
|
请注意,在循环中增加了i
的值,否则while
循环永远不会终止,因为它变成了无限循环。 终止程序在无限循环中运行的唯一方法是手动退出它或JVM内存不足时。
请注意,如果布尔表达式返回false
,则while
循环内的语句将不会执行。 所以while
循环中的语句有可能永远不会执行。
示例2. Java迭代循环与迭代器
Java while
循环在java中经常与迭代器一起使用。 下面来看一个使用while
循环迭代ArrayList
的简短示例。
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
示例3. while无限循环示例
有时希望循环无限运行。在这种情况下,可以使用while
循环。 无限运行的一个例子是在特定位置连续查找文件,如果找到则然后处理它。 下面是java中while
循环的伪代码示例。
1 |
|
如果运行上面的程序,需要在终端上使用Ctrl + C
手动退出程序。 如果使用的是Eclipse,则会有一个红色按钮来终止当前正在运行的程序。
for循环
for
循环是一种重复控制结构,用于有效地编写需要执行特定次数的循环。当知道要重复任务的次数时,for
循环就很有用。
语法
for
循环的语法是 -
1 |
|
在上面语法中,
- 首先执行初始化(
initialization
)步骤,并且仅执行一次。此步骤用于声明和初始化循环控制变量,此步骤以分号(;
)结束。 - 接下来,计算布尔表达式(
boolean_expression
)。 如果结果为:true
,则执行循环体。 如果为false
,则不执行循环体,控制跳转到for
循环之后的下一个语句。 - 在执行
for
循环体之后,控件跳回到update
语句。 此语句用于更新任何循环控制变量。此语句可以留空,最后是分号(;
)。 - 现在再次评估布尔表达式(
boolean_expression
)。 如果结果为:true
,则循环执行并重复该过程(循环体,然后是更新步骤,然后是布尔表达式)。 布尔表达式为false
后,for
循环终止。
java中有三种类型的for
循环,它们分别如下:
- 简单
for
循环 for-each
或增强for
循环for
循环与标签
1. 简单for循环实例
Java中的简单for
循环与C/C ++相同。可以初始化变量,检查条件和增量/减量值。
假设要打印5
到10
的整数,在这种情况下可以使用基本的for
循环。
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
示例2. for增强型循环
Java中的for each
循环也称为增强型循环。可以使用for each
迭代数组或集合元素。Java for each
循环是推荐的循环方式,因为它的代码编写比较简单和紧凑。
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
从上面的例子中可以看出,如果for
循环中只有一个语句,不需要将它们放在花括号{}
中。
示例3. for循环与标签
可以在for
循环中添加一个标签,它对break
和continue
语句有用,可以退出外循环。 请注意,默认情况下,break
和continue
语句仅适用于内部循环。 下面是带有标签的for
循环的示例以及它如何与continue
语句一起使用。
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
do…while循环
其实笔者基本也只在算法题里面用的比较多
do...while
循环类似于while
循环,除了do...while
循环保证至少执行一次。
语法
以下是do...while
循环的语法 -
1 |
|
请注意,布尔表达式在循环的末尾,因此循环中的语句在测试布尔值之前已经执行了一次。
如果布尔表达(boolean_expression
)式评估结果为true
,则控制跳回到do
语句,循环中的语句再次执行。 重复此过程,直到布尔表达式(boolean_expression
)评估结果为false
。
示例1. do…while循环
这是一个简单的java do while
循环示例,用于打印5
到10
之间的数字。
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
示例2. do…while无限循环
通过在do...while
循环中将布尔表达式使用true
值来创建无限循环。下面是一个简单的做java无限循环的例子(伪代码)。
1 |
|
请注意,如果在终端中执行程序,则可使用Ctrl + C
手动退出应用程序。 如果已在Eclipse IDE中执行程序,则会有一个红色按钮来终止程序。
do…while与while循环比较
当希望在循环内的语句至少执行一次时,则应该使用do...while
循环。 否则,使用while
循环总是更好选择。Java while
循环看起来比do...while
循环更干净。
循环控制语句
循环控制语句将执行从正常执行顺序更变。 当执行离开作用域时,将销毁在该作用域中创建的所有自动对象。
Java支持以下控制语句,可通过单击以下每个链接来了解和学习。
编号 | 控制语句 | 描述 |
---|---|---|
1 | break语句 | 终止循环或switch 语句,并立即将执行转移到在循环或switch 之后的语句。 |
2 | continue语句 | 使循环跳过其主体的其余部分,并在重复之前立即重新测试其状态。 |
break语句
Java编程语言中的break
语句有以下两种用法 -
- 当在循环内遇到
break
语句时,循环立即终止,程序控制在循环体之后的下一个语句处重新开始。 - 它可以用于在
switch
语句中终止一个case
。
语法
break
的语法是循环内的单个语句 -
1 |
|
示例1. break简单示例
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
示例2. break语句示例
在这个示例中,演示如何在java的for
循环,while循环和do-while
循环中使用break
语句。
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
请注意,如果删除break
语句,程序的输出将没有任何差异。 对于此示例中的小型迭代,没有的性能问题。 但是如果迭代器次数很大,那么它可以节省大量的处理时间。
示例3. Java break标签break
语句标签化用于终止外部循环,应该标记循环以使其起作用。这是一个演示java break
标签语句用法的示例。
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
continue语句
Java continue语句用于继续循环。 它继续程序的当前流程,并在指定条件下跳过剩余的代码。在内循环的情况下,它仅继续内循环。
语法:
1 |
|
Java continue语句示例
1 |
|
执行上面示例代码,得到如下结果 -
1 |
|
Java continue语句与内循环
如果在内循环中使用continue
语句,它将继续内循环。
示例:
1 |
|
执行上面示例代码,得到如下结果 -
1 |
|
Java决策制定
Java编程语言提供以下类型的决策制定语句。 可通过单击以下链接来了解和学习。
编号 | 语句 | 描述 |
---|---|---|
1 | if语句 | if 语句由布尔表达式后跟一个或多个语句组成。 |
2 | if…else语句 | if 语句后面可以跟一个可选的else 语句,else 语句在布尔表达式为false 时执行。 |
3 | switch语句 | switch 语句允许测试变量与值列表的相等性。 |
if语句
if
语句由一个布尔表达式后跟一个或多个语句组成。
语法
以下是if
语句的语法 -
1 |
|
如果布尔表达式(boolean_expression
)的计算结果为true
,那么将执行if
语句中的代码块。 如果计算结果为false
,将执行if
语句结束后(在结束大括号之后)的第一组代码。
示例代码
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
if…else语句
if
语句后面可以跟一个可选的else
语句,else
语句在布尔表达式为false
时执行。
语法
以下是if...else
语句的语法 -
1 |
|
如果布尔表达式的计算结果为true
,那么将执行if
代码块,否则将执行else
代码块。
示例代码
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
if…else if…else语句
if
语句之后可以跟一个可选的else if
语句,这对于使用if...else if
语句测试各种条件非常有用。
当使用if
,else if
,else
语句时,需要记住几点:
- 一个
if
语句之后可以有零个或一个else
语句,但它必须在else...if
之后。 if
可以有零或多个else...if
,并且它们必须在else
语句之前。- 当有一个
else if
条件匹配成功,其余的else...if
或者else
都将不会执行。
语法
以下是if...else
语句的语法 -
1 |
|
示例代码
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
switch语句
switch
语句用于测试变量与值列表的相等性。 每个值称为一个case
,并且针对每种情况检查对应的变量值。
语法
增强for
循环的语法是 -
1 |
|
以下是适用于switch
语句的规则 -
switch
语句中使用的变量只能是整数,可转换为整数(如:byte
,short
,char
),字符串和枚举类型。- 可以在
switch
中包含任意数量的case
语句。每个case
后跟要与之比较的值和冒号。 case
的值必须与switch
中的变量具有相同的数据类型,并且必须是常量或文字。- 当
switch
的变量等于case
中的值时,该case
之后的语句将一直执行,直到达到break
语句。 - 当达到
break
语句时switch
终止,控制流跳转到switch
语句块后面的下一行代码。 - 不是每个
case
都需要包含break
语句。 如果没有指定break
语句,则控制流将落到后续case
中,直到达到break
语句。 switch
语句可以有一个可选的default
,它必须出现在switch
语句的末尾。 当没有任何case
匹配时,执行default
中的代码块。default
中不需要break
语句。
示例1
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
示例2
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
Java方法
Java中的方法是一组语句,它们组合在一起以执行各种操作。 例如,当调用System.out.println()
方法时,系统实际上会执行多个语句,以便在控制台上显示消息。
下面将学习如何使用或不使用返回值创建自己的方法,使用或不使用参数调用方法,以及在程序设计中应用方法抽象。
创建方法
下面来看看方法的语法 -
1 |
|
在上面语法中,
public static
− 修辞符int
− 返回值的类型methodName
− 方法的名称a, b
− 形式参数int a, int b
− 参数列表
方法定义由方法头和方法体组成。以下语法中显示了相同的内容 -
1 |
|
上面显示的语法包括 -
modifier
- 它定义方法的访问类型,它可能是:public
,private
,protected
或不指定。returnType
- 方法可以返回一个值。nameOfMethod
- 这是方法名称,方法签名由方法名称和参数列表组成。Parameter List
- 参数列表,它是方法的类型,顺序和参数数量。 这些是可选的,方法可能包含零参数。method body
- 方法体定义方法对语句的作用。
示例
以下代码中定义了min()
方法。 这个方法有两个int
类型的参数:num1
和num2
,并返回两者之间的最大值 -
1 |
|
方法调用
可通过调用方法来使用方法,调用方法有两种方式,即方法有返回值或无返回任何值。
方法调用的过程很简单。 当程序调用方法时,程序控制将转移到被调用的方法。 这个被调用的方法然后在两个条件下将控制权返回给调用者,即 -
return
语句被执行。- 它到达方法的结束,即右大括号(
}
)。
对返回void
的方法的调用 -
1 |
|
对有返回值的方法的调用 -
1 |
|
以下是演示如何定义方法以及如何调用方法的示例 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
void关键字
void
关键字允许创建不返回值的方法。在下面的例子中有一个返回值是void
的方法methodRankPoints
,它不返回任何值。 调用void
方法必须是一个语句,即methodRankPoints(245.67);
. 它是一个以分号结尾的Java语句,如以下示例所示 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
按值传递参数
在按值传递参数时需要传递参数。它们的顺序应与方法规范中的参数顺序相同。参数可以通过值或引用传递。
通过值传递参数是使用参数调用方法。 通过这样将参数值将传递给参数。
示例
以下程序显示了按值传递参数的示例。 即使在方法调用之后,参数的值仍保持不变。
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
方法重载
当一个类有两个或多个同名但方法不同参数的方法时,称为方法重载。 它与重写不同。 在重写中,方法具有相同的方法名称,类型,参数数量等。
在前面讨论的用于查找最小整数类型数的示例中,假设想要查找两个double
类型的最小数值。 可引入重载的概念以创建具有相同名称但不同参数的两个或更多方法。
参考以下示例代码 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
重载方法使程序可读。这里,两个方法由相同的名称给出但具有不同的参数类型。结果是求int
类型和double
类型的最小数。
使用命令行参数
有时希望在运行程序时将一些信息传递给程序。它是通过将命令行参数传递给main()
来实现的。
命令行参数是执行时在命令行上直接跟随程序名称的信息。 要访问Java程序中的命令行参数非常简单。 它们作为字符串存储在传递给main()
的String
类型数组中。
示例
以下程序显示传递给程序的所有命令行参数 -
1 |
|
使用以下方式执行此程序 -
1 |
|
那么将得到以下结果:
1 |
|
this关键字
this
是Java中的一个关键字,用作对当前类对象的引用,在实例方法或构造函数中。 使用它可以引用类的成员,例如:构造函数,变量和方法。
注 -
this
关键字仅在实例方法或构造函数中使用。
通常,this
关键字用于 -
如果实例变量在构造函数或方法中具有相同的名称,则将它们与局部变量区分开来。
1
2
3
4
5
6class Student {
private int age;
Student(int age) {
this.age = age;
}
}从类中的其他方法调用一种类型的构造函数(参数化构造函数或默认值),称为显式构造函数调用。
1
2
3
4
5
6
7
8
9class Student {
int age;
Student() {
this(20);
}
Student(int age) {
this.age = age;
}
}
以下是使用this
关键字访问类成员的示例 -
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
变量参数(var-args)
JDK 1.5允许将可变数量的相同类型的参数传递给方法。方法中的参数声明如下 -
1 |
|
在方法声明中,指定类型后跟省略号(...
)。 在方法中只能指定一个可变长度参数,并且此参数必须是最后一个参数。
1 |
|
执行上面示例代码,得到以下结果 -
1 |
|
finalize()方法
finalize()方法在垃圾收集器对象最终销毁之前调用,它可用于确保对象完全终止。例如,可以使用finalize()
来确保该对象拥有的打开文件已关闭。
要将终结器添加到类中,只需定义finalize()
方法即可。只要Java方法要回收该类的对象,它就会调用该方法。
在finalize()
方法中,将指定在销毁对象之前必须执行的操作。finalize()
方法有这种一般形式 -
1 |
|
这里,关键字protected
是一个修辞符,它阻止通过类外部定义的代码访问finalize()
。
我们无法知道Java何时或甚至是否将执行finalize()
方法。如果程序在垃圾收集发生之前结束,则finalize()
将不会执行。
Java正则表达式
Java提供了java.util.regex
包,用于与正则表达式进行模式匹配。 Java正则表达式与Perl编程语言非常相似,非常容易学习。
正则表达式是一种特殊的字符序列,可使用模式中的专用语法来匹配或查找其他字符串或字符串集。 它们可用于搜索,编辑或操作文本和数据。
java.util.regex
包主要由以下三个类组成 -
Pattern
类 -Pattern
对象是正则表达式的编译表示。Pattern
类不提供公共构造函数。 要创建模式,需要首先调用它的公共静态compile()
方法,然后返回Pattern
对象。 这些方法接受正则表达式作为第一个参数。Matcher
类 -Matcher
对象是解释模式并对输入字符串执行匹配操作的引擎。 与Pattern
类一样,Matcher
没有定义公共构造函数。 通过在Pattern
对象上调用matcher()
方法获取Matcher
对象。PatternSyntaxException
-PatternSyntaxException
对象是未经检查的异常,指示正则表达式模式中的语法错误。
捕获组
捕获组是将多个字符视为一个单元的一种方法。 它们是通过将要分组的字符放在一组括号中来创建的。 例如,正则表达式(dog
)创建包含字母d
,o
和g
的单个组。
捕获组通过从左到右计算它们的左括号来编号。 在表达式((A)(B(C)))
中,例如,有四个这样的组 -
((A)(B(C)))
(A)
(B(C))
(C)
要查找表达式中存在多少个组,请在Matcher
对象上调用groupCount()
方法。 groupCount()
方法返回一个int
类型值,显示Matcher
模式中存在的捕获组数。
还有一个特殊组,即组0
,它始终代表整个表达式。 该组未包含在groupCount()
报告的总数中。
示例
以下示例说明如何从给定的字母数字字符串中查找数字字符串 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
正则表达式语法
下面列出了Java中可用的所有正则表达式元字符语法 -
编号 | 子表达式 | 匹配 |
---|---|---|
1 | ^ |
匹配行的开头。 |
2 | $ |
匹配行的结尾。 |
3 | . |
匹配除换行符之外的任何单个字符,使用m 选项也可以匹配换行符。 |
4 | [...] |
匹配括号中的任何单个字符。 |
5 | [^...] |
匹配括号内的任何单个字符。 |
6 | \A |
整个字符串的开头。 |
7 | \z |
整个字符串的结尾。 |
8 | \Z |
除允许的最终行终止符之外的整个字符串的结尾。 |
9 | re* |
匹配前面表达式的0 次或更多次出现。 |
10 | re+ |
匹配前面表达式的1 次或更多次出现。 |
11 | re? |
匹配前面表达式的0 或1 次出现。 |
12 | re{n} |
准确匹配前面表达式的n 次出现次数。 |
13 | re{n,} |
准确匹配前面表达式的n 次以上出现次数。 |
14 | aΙb | 匹配a 或b 。 |
15 | (re) |
对正则表达式进行分组并记住匹配的文本。 |
16 | (?: re) |
将正则表达式分组而不记住匹配的文本。 |
17 | (?> re) |
匹配独立模式而无需回溯。 |
18 | \w |
匹配单词字符。 |
19 | \W |
匹配非单词字符。 |
20 | \s |
匹配空白符,相当于:[\t\n\r\f] |
21 | \S |
匹配非空白。 |
22 | \d |
匹配数字,相当于:[0-9] 。 |
23 | \D |
匹配非数字。 |
24 | \A |
匹配字符串的开头。 |
25 | \Z |
匹配字符串的结尾。如果存在换行符,则它在换行符之前匹配。 |
26 | \z |
匹配字符串的结尾。 |
27 | \G |
匹配最后一个匹配结束的点。 |
28 | \n |
反向引用以捕获组号:n 。 |
29 | \b |
在括号外部匹配单词边界,在括号内匹配退格(0x08 )。 |
30 | \B |
匹配非字边界。 |
31 | \n ,\t |
匹配换行符,回车符,制表符等。 |
32 | \E |
转义(引用)所有字符直到\E 。 |
33 | \Q |
结束以\Q 开头引用。 |
start()和end()方法
以下是计算字符串中:cat
一词的出现次数示例 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
可以看到此示例使用单词边界来确保字母:c
,a
,t
不仅仅是较长单词中的子字符串。 它还提供了有关输入字符串中匹配发生位置的一些有用信息。
start
方法返回上一个匹配操作期间给定组捕获的子序列的起始索引,end
返回匹配的最后一个字符的索引加1
。
matches和lookingAt方法
matches()
和lookingAt()
方法都尝试将输入序列与模式匹配。 然而,不同之处在于匹配需要匹配整个输入序列,而查找则不需要。
两种方法总是从输入字符串的开头开始。 以下是上述方法的示例 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
replaceFirst和replaceAll方法replaceFirst()
和replaceAll()
方法替换匹配给定正则表达式的文本。 正如其名称所示,replaceFirst()
替换第一个匹配项,replaceAll()
替换所有匹配项。
以下是上述功能的示例 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|
appendReplacement和appendTail方法
Matcher
类还提供了appendReplacement
和appendTail
方法来替换文本。
以下是上述方法的示例 -
1 |
|
执行上面示例代码,得到以下结果:
1 |
|