Java 基础
Java程序的基本结构
-
包声明
package <包名>;
-
导入语句
import <包名>.<类名>; // 导入特定类 import <包名>.*; // 导入整个包
-
类定义
public class Main { // 类体 }
-
主方法
public static void main(String[] args) { // 程序代码 }
语法基础
-
标识符
用来标识类名、变量名、方法名、类型名、数组名、文件名的有效字符序列称为标识符。简单地说,标识符就是一个名字。
Java语言规定标识符由字母、下划线、美元符号和数字组成,并且第一个字符不能是数字。标识符中的字母是区分大小写的。
-
关键字
关键字就是Java语言中已经被赋予特定意义的一些单词。
功能分类 关键字 访问控制 private、protected、public 类、方法和变量修饰符 abstract、class、enum、extends、final、implements 程序控制 interface、native、new、static、strictfp、synchronized、transient、volatile 错误处理 break、continue、return、do、while、if、else、for 包相关 instanceof、switch、case、default 基本数据类型 assert、try、catch、finally、throw、throws 变量引用 package、import 保留字 boolean、byte、char、double、float、int、long、short -
基本数据类型
数据类型 关键字 占用位数 取值范围/值域 布尔型 boolean 8位 true, false 字符型 char 16位 ‘\u0000’~’\uFFFF’ (0~65535) 字节型 byte 8位 -128~127 短整型 short 16位 -32768~32767 整型 int 32位 -2,147,483,648~2,147,483,647 长整型 long 64位 -2⁶³~2⁶³-1 浮点型 float 32位 1.40129846432481707e-45~3.40282346638528860e+38 双精度型 double 64位 4.94065645841246544e-324~1.79769313486231570e+308 数据精度(由低至高):byte short int long float double
-
基本数据类型的转换
当把级别低的变量的值赋给级别高的变量时,系统自动完成数据类型的转换。
当把级别高的变量的值赋给级别低的变量时,必须使用显示类型转换运算。显示转换的格式:
(<数据类型>)<数值>
-
-
运算符
-
算术运算符
运算符 描述 示例 +
加法 a + b
-
减法 a - b
*
乘法 a * b
/
除法 a / b
%
取模(余数) a % b
++
自增 a++
或++a
--
自减 a--
或--a
注意:
++a
(前缀) 和a++
(后缀) 的区别在于表达式的值不同。 -
关系运算符
运算符 描述 示例 ==
等于 a == b
!=
不等于 a != b
>
大于 a > b
<
小于 a < b
>=
大于或等于 a >= b
<=
小于或等于 a <= b
-
逻辑运算符
运算符 描述 示例 &&
逻辑与 a && b
||
逻辑或 a || b
!
逻辑非 !a
短路特性:
&&
和||
具有短路特性,即如果第一个操作数已经能确定结果,则不会计算第二个操作数。 -
位运算符
运算符 描述 示例 &
位与 a & b
|
位或 a | b
^
位异或 a ^ b
~
位非 ~a
<<
左移 a << b
>>
右移(带符号) a >> b
>>>
右移(无符号) a >>> b
-
赋值运算符
运算符 描述 示例 等价于 =
赋值 a = b
+=
加后赋值 a += b
a = a + b
-=
减后赋值 a -= b
a = a - b
*=
乘后赋值 a *= b
a = a * b
/=
除后赋值 a /= b
a = a / b
%=
取模后赋值 a %= b
a = a % b
&=
位与后赋值 a &= b
a = a & b
|=
位或后赋值 a |= b
a = a | b
^=
位异或后赋值 a ^= b
a = a ^ b
<<=
左移后赋值 a <<= b
a = a << b
>>=
右移后赋值 a >>= b
a = a >> b
>>>=
无符号右移后赋值 a >>>= b
a = a >>> b
-
条件运算符
<条件> ? <表达式1> : <表达式2>
-
输入输出
-
输出
System.out.printf("<格式字符串>",<参数>); //格式化输出 System.out.print(<基本类型或对象>); //普通输出 System.out.println(<基本类型或对象>); //换行输出
-
输入
- 导入 Scanner 类
import java.util.Scanner;
- 创建 Scanner 对象
Scanner scanner = new Scanner(System.in);
-
读取不同类型的数据
方法 描述 示例 next()
读取下一个字符串(以空格分隔) String s = scanner.next();
nextLine()
读取一行文本 String line = scanner.nextLine();
nextInt()
读取下一个整数 int num = scanner.nextInt();
nextDouble()
读取下一个双精度浮点数 double d = scanner.nextDouble();
nextBoolean()
读取下一个布尔值 boolean b = scanner.nextBoolean();
hasNext()
检查是否还有输入 while(scanner.hasNext()) {...}
-
useDelimiter 方法
useDelimiter() 是 Scanner 类的一个重要方法,用于设置输入的分隔模式,可以灵活地控制如何将输入内容分割成多个 token。
Scanner useDelimiter(String pattern) Scanner useDelimiter(Pattern pattern)
- pattern:可以是一个字符串形式的正则表达式,或者是一个预编译的 Pattern 对象
- return:Scanner 对象
-
使用字符串作为分隔符
scanner.useDelimiter(","); // 使用逗号作为分隔符 while(scanner.hasNext()) { System.out.println(scanner.next()); }
-
使用正则表达式作为分隔符
scanner.useDelimiter("\\d+"); // 使用数字作为分隔符 while(scanner.hasNext()) { System.out.println(scanner.next()); }
-
使用多个分隔符
scanner.useDelimiter(" and | or "); // 使用" and "或" or "作为分隔符 while(scanner.hasNext()) { System.out.println(scanner.next()); }
数组
-
数组声明
// 声明方式1:推荐 <数据类型>[] <数组名>; // 声明方式2:合法但不推荐 <数据类型> <数组名>[];
-
初始化
-
静态初始化
<数据类型>[] <数组名> = {<元素1, 元素2, ...>}; //一维数组 <数据类型>[][] <数组名> = {{<第1行元素>},{<第2行元素>},...}; //二维数组
-
动态初始化
<数据类型>[] <数组名> = new <数据类型>[<长度>]; //一维数组 <数据类型>[][] <数组名> = new <数据类型>[<行数>][<列数>]; //二维数组
-
访问元素
<数组名>[<索引>] //一维数组 <数组名>[<行索引>][<列索引>] //二维数组
-
数组长度
<数组名>.length
-
语句应用
-
分支语句
-
if 语句
if (<条件表达式>) { // 条件为 true 时执行的代码 }
if (<条件表达式>) { // 条件为 true 时执行的代码 } else { // 条件为 false 时执行的代码 }
if (<条件1>) { // 条件1为 true 时执行的代码 } else if (<条件2>) { // 条件2为 true 时执行的代码 } else { // 所有条件都为 false 时执行的代码 }
-
switch 语句
switch (<表达式>) { case <值1>: // 代码块1 break; case <值2>: // 代码块2 break; // 可以有任意数量的 case 语句 default: // 默认代码块 }
-
-
循环语句
-
while 循环
while (<条件表达式>) { // 循环体 }
-
do-while 循环
do { // 循环体 } while (<条件表达式>);
-
for 循环
for (<初始化>; <条件判断>; <迭代更新>) { // 循环体 }
-
增强 for 循环 (for-each)
for (<元素类型> <变量名> : <数组或集合>) { // 循环体 }
-
-
中断流程控制
-
break 语句
立即终止当前循环或 switch 语句。
break;
带标签的 break,跳出指定的外层循环。
<标签名>: // 标签 <循环语句>{ // 循环体 <循环语句>{ // 循环体 break <标签名>; // 直接跳出外层循环 } }
-
continue 语句
跳过当前循环的剩余部分,直接进入下一次循环。
continue;
跳转到指定标签的循环的下一次迭代。
<标签名>: // 标签 <循环语句>{ // 循环体 <循环语句>{ // 循环体 break <标签名>; // 跳过外层循环的当前迭代 } }
-
return 语句
用于从方法中返回,可以带返回值(对于非void方法)或不带返回值(对于void方法)。
return [<返回值>];
-
面相对象
类
-
修饰符
- 访问修饰符
- public:所有类均可访问
- protected:同包或子类可访问
- 默认(无):同包可访问
- private:仅本类可访问
- 其他修饰符
- final:类不能被继承
- abstract:抽象类,不能实例化
- static:静态嵌套类(内部类)
- strictfp:浮点运算严格遵守IEEE 754标准
- 访问修饰符
-
类的定义
[<访问修饰符>] [<修饰符>] class <类名> [extends <父类>] [implements <接口列表>] { // 成员变量(字段) // 构造方法 // 成员方法 // 初始化块 // 内部类/接口 }
-
成员变量
[<访问修饰符>] [static/final/transient/volatile] <数据类型> <变量名> [= <初始值>];
-
成员方法
[<访问修饰符>] [static/final/abstract] <返回类型> <方法名>([<参数列表>]) [throws <异常列表>] { // 方法体 [return <返回值>;] }
-
返回类型
- 基本类型/引用类型:返回具体值
- void:无返回值
- 可以是泛型类型
-
参数传递
- 值传递:基本类型传递值副本
- 引用传递:对象传递引用副本
-
方法重载
方法重载是指在同一个类中,允许存在多个同名方法,只要它们的参数列表不同(参数类型、参数个数或参数顺序不同)。- 方法名必须相同
- 参数列表必须不同(至少一项不同)
- 返回类型可以相同也可以不同
- 访问修饰符可以相同也可以不同
- 可以抛出不同的异常
-
-
构造方法
[<访问修饰符>] <类名>([<参数列表>]) { // 初始化代码 }
-
this关键字
-
当成员变量与局部变量同名时,使用this可以明确指定访问的是成员变量:
this.<变量名>
-
在构造方法中,可以使用this()调用本类的其他构造方法,必须放在构造方法的第一行:
[<访问修饰符>] <类名>([<参数列表>]) { this(<参数列表>); }
-
返回当前对象:
return this;
-
对象
-
对象的创建
<类名> <对象名> = new <构造方法>([<参数>]);
-
对象的使用
-
访问成员变量
<对象名>.<变量名>;
-
调用成员方法
<对象名>.<方法名>([<参数>]);
-
继承
-
定义语法
class 子类 extends 父类 { // 子类特有的属性和方法 }
-
访问权限
修饰符 本类 同包 子类 其他 private ✓ ✗ ✗ ✗ 默认 ✓ ✓ ✗ ✗ protected ✓ ✓ ✓ ✗ public ✓ ✓ ✓ ✓ -
方法重写
class <父类> { [<访问修饰符>] [static/final/abstract] <返回类型> <方法名>([<参数列表>]) [throws <异常列表>] { // 方法体 } } class <子类> extends <父类> { @Override [<访问修饰符>] [static/final/abstract] <返回类型> <方法名>([<参数列表>]) [throws <异常列表>] { // 方法体 } }
-
super关键字
-
当子类和父类有同名成员变量时,使用super可以访问父类的变量:
super.<>变量名
-
当子类重写了父类方法时,可以使用super调用父类的原始方法:
super.<方法名>([<参数列表>]);
-
在子类构造方法中使用super()调用父类构造方法,必须放在子类构造方法的第一行:
[<访问修饰符>] <类名>([<参数列表>]) { super(<参数列表>); }
-
多态
-
形式
<父类类型> <变量名> = new <子类类型>();
-
向上转型
<父类类型> <引用名> = new <子类类型>();
-
向下转型
<子类类型> <引用名> = (<子类类型>)<父类引用>;
抽象类
-
抽象类定义
[<访问修饰符>] abstract class <类名> { // 成员变量 // 构造方法 // 抽象方法 // 具体方法 }
-
抽象方法
[<访问修饰符>] abstract <返回类型> <方法名>([<参数列表>]);
- 抽象方法必须存在于抽象类或接口中
接口
-
接口定义
[访问修饰符] interface 接口名 { // 常量声明 // 抽象方法 // 默认方法 // 静态方法 // 私有方法 }
- 不能直接创建对象
- 可以包含抽象方法、默认方法、静态方法和私有方法
- 可以包含常量(public static final)
- 支持多重实现(一个类可以实现多个接口)
-
方法
-
抽象方法
[public] [abstract] <返回类型> <方法名>([<参数列表>]);
- 默认修饰符:public abstract(可省略)
- 没有方法体
- 实现类必须重写所有抽象方法
-
默认方法
[public] default <返回类型> <方法名>([<参数列表>]) { // 方法体 }
- 使用default关键字
- 有方法实现
- 实现类可选择重写或直接继承
-
静态方法
[public] static <返回类型> <方法名>([<参数列表>]) { // 方法体 }
- 使用static关键字
- 有方法实现
- 只能通过接口名调用
-
私有方法
private 返回类型 方法名([参数列表]) { // 方法体 }
-
-
常量
//(public static final可省略) [public] [static] [final] <数据类型> <常量名> = <值>;
特性 常量 抽象方法 默认方法 静态方法 关键字 (无) (无) default static 默认修饰符 public static final public abstract public public 实现 必须初始化 无实现 有实现 有实现 调用方式 接口名.常量名 实现类实例调用 实现类实例调用 接口名.方法名() 可被重写 否 必须 可选 否 -
接口的实现
-
类实现接口
class <类名> implements <接口1>[, <接口2>, ...] { // 必须实现所有抽象方法(除非是抽象类) }
-
接口继承接口
interface <子接口> extends <父接口1>[, <父接口2>, ...] { // 可以添加新方法 }
-
内部类
-
成员内部类
[<访问修饰符>] class <外部类> { // 外部类成员 class <内部类> { // 内部类成员 } }
-
匿名内部类
<类名> <对象名> = new <类名>(<参数列表>) { // 类体 }
常用类
-
String类
-
创建 String 对象
String <变量名> = "<字符串内容>"; // 直接赋值 String <变量名> = new String("<字符串内容>"); // 构造方法创建 char[] <字符数组名> = {'H','e','l','l','o'}; String <变量名> = new String(<字符数组名>); // 从字符数组创建 byte[] <字节数组名> = {72, 101, 108, 108, 111}; String <变量名> = new String(<字节数组名>); // 从字节数组创建
-
常用方法
int <长度变量> = <字符串变量>.length(); // 获取长度 char <字符变量> = <字符串变量>.charAt(<索引>); // 获取字符 int <索引变量> = <字符串变量>.indexOf("<子串>"); // 查找子串位置 boolean <相等判断> = <字符串1>.equals(<字符串2>); // 区分大小写比较 boolean <忽略大小写判断> = <字符串1>.equalsIgnoreCase(<字符串2>); // 不区分大小写 int <比较结果> = <字符串1>.compareTo(<字符串2>); // ASCII码差值 String <修剪结果> = <原字符串>.trim(); // 去除首尾空格 String <修剪结果> = <原字符串>.strip(); // 移除首尾空白 String <大写结果> = <原字符串>.toUpperCase(); // 转大写 String <小写结果> = <原字符串>.toLowerCase(); // 转小写 String <替换结果> = <原字符串>.replace('<原字符>', '<新字符>'); // 字符替换 String[] <分割数组> = <分割字符串>.split("<分隔符>"); // 字符串分割 String <连接结果> = String.join("<连接符>", <分割数组>); // 字符串连接 String <字符串变量> = String.valueOf(<整型变量>); // 整形转字符串
-
-
包装类
-
Integer类(整型包装类)
-
对象创建
Integer <变量名> = Integer.valueOf(<整型值>); // 推荐方式 Integer <变量名> = Integer.valueOf("<数字字符串>"); // 从字符串创建 Integer <变量名> = new Integer(<整型值>); // 已弃用方式
-
类型转换
int <基本类型变量> = <Integer对象>.intValue(); // 拆箱操作 String <字符串变量> = <Integer对象>.toString(); // 转字符串 String <进制字符串> = Integer.toBinaryString(<整型值>); // 转二进制 String <进制字符串> = Integer.toHexString(<整型值>); // 转十六进制
-
字符串解析
int <整型值> = Integer.parseInt("<数字字符串>"); // 解析十进制 int <整型值> = Integer.parseInt("<数字字符串>", <进制>); // 指定进制解析 Integer <对象> = Integer.decode("<数字字符串>"); // 自动识别进制
-
比较与运算
int <比较结果> = Integer.compare(<值1>, <值2>); // 比较 boolean <相等判断> = <对象1>.equals(<对象2>); // 对象比较 int <求和结果> = Integer.sum(<值1>, <值2>); // 求和 int <最大值> = Integer.max(<值1>, <值2>); // 取最大值
-
-
Double类(双精度浮点包装类)
-
对象创建
Double <变量名> = Double.valueOf(<双精度值>); // 推荐方式 Double <变量名> = Double.valueOf("<数字字符串>"); // 从字符串创建 Double <变量名> = <双精度值>; // 自动装箱
-
类型转换
double <基本类型> = <Double对象>.doubleValue(); // 拆箱 String <字符串> = <Double对象>.toString(); // 转字符串 int <整型值> = <Double对象>.intValue(); // 转int(截断)
-
字符串解析
double <双精度值> = Double.parseDouble("<数字字符串>"); String <十六进制> = Double.toHexString(<双精度值>);
-
-
Character类(字符包装类)
-
对象创建
Character <变量名> = Character.valueOf('<字符>'); // 推荐方式 Character <变量名> = '<字符>'; // 自动装箱
-
字符判断
boolean <是否字母> = Character.isLetter(<字符>); boolean <是否数字> = Character.isDigit(<字符>); boolean <是否空白> = Character.isWhitespace(<字符>); boolean <是否大写> = Character.isUpperCase(<字符>);
-
字符转换
char <小写字符> = Character.toLowerCase(<字符>); char <大写字符> = Character.toUpperCase(<字符>); int <代码点> = Character.codePointAt(<字符数组>, <索引>);
-
-
Boolean类(布尔包装类)
-
对象创建
Boolean <变量名> = Boolean.valueOf(<布尔值>); // 推荐方式 Boolean <变量名> = Boolean.valueOf("<字符串>"); // 从字符串创建 Boolean <变量名> = <布尔值>; // 自动装箱
-
字符串解析
boolean <布尔值> = Boolean.parseBoolean("<字符串>"); Boolean <对象> = Boolean.valueOf("true"); // 不区分大小写
-
-
-
ArrayList
List<<元素类型>> <列表名> = new ArrayList<<元素类型>>(); // 创建ArrayList <列表名>.add(<元素>); // 添加元素 <元素类型> <元素变量> = <列表名>.get(<索引>); // 获取元素 <列表名>.remove(<索引>); // 按索引删除 <列表名>.remove(<元素>); // 按元素删除 int <大小变量> = <列表名>.size(); // 获取大小
-
HashMap
Map<<键类型>,<值类型>> <映射名> = new HashMap<<键类型>,<值类型>>(); // 创建HashMap <映射名>.put(<键>,<值>); // 添加键值对 <值类型> <值变量> = <映射名>.get(<键>); // 获取值 <映射名>.remove(<键>); // 删除键值对 boolean <存在结果> = <映射名>.containsKey(<键>); // 检查键是否存在