java(上)
模块一
1.JDK,JRE,JVM
知识点 | 核心内容 | 易混淆点 |
JDK定义 | Java Development Kit(Java开发工具包),包含开发所需全部工具 | JDK包含JRE的关系容易混淆 |
JRE定义 | Java Runtime Environment(Java运行环境),包含JVM和核心类库 | JRE与JDK的包含关系 |
JVM作用 | Java虚拟机,实现跨平台运行的核心组件 | JVM在JRE中的位置 |
开发工具 | 包含javac(编译)、java(运行)、jdb(调试)、jhat(内存分析)等工具 | 各工具的具体用途区分 |
版本变化 | JDK 9开始取消独立JRE目录,采用模块化技术优化运行时环境 | 新旧版本目录结构差异 |
模块化优势 | 允许创建最小运行时环境,提高运行效率,减少资源占用 | 与传统JRE部署方式的对比 |
安装建议 | 只需安装JDK即可获得完整开发环境(包含JRE和JVM) | JDK版本选择注意事项 |
2.API文档注释
知识点 | 核心内容 | 重点 |
文档注释的作用 | 通过Javadoc生成API文档,帮助他人快速理解代码功能、类用途及方法说明 | 需区分普通注释与文档注释的语法差异(/** */ vs //或/* */) |
Javadoc命令语法 | javadoc -d [文件夹名] -author -version [文件名.java] | 参数顺序易错(如-d必须在前),忽略警告可能影响文档完整性 |
API文档结构 | 包含类描述、作者、版本、方法功能说明(如main为程序入口) | 方法注释需标注参数(@param),否则生成警告 |
文档注释内容规范 | 类注释需说明整体功能,方法注释需明确用途(如main是虚拟机执行入口) | 注解(@author、@version)需与注释内容分离 |
3.print与println区别
知识点 | 核心内容 | 重点 |
print与println的区别 | print和println都是输出语句 | 区分print和println的输出效果 |
println输出后自带换行效果 | println输出后会自动换到下一行 | |
print输出后不带换行效果 | print输出后会继续在同一行显示后续内容 | |
JAVA操作小技巧 | 复制当前行:ctrl+d | 快捷键使用,提高编码效率 |
一次操作多行:预留空间,按住ALT键不放,鼠标往下拉 | 适用于需要同时编辑多行代码的情况 |
模块二
4.常量
知识点 | 核心内容 | 重点 |
常量定义 | 在代码运行过程中,其值不会发生改变的数据 | 区分常量与变量的关键:值是否可变 |
整数常量 | 包含所有正负整数(如 -1, 0, 100) | 无特殊易错点 |
小数常量 | 带小数点的数值(如 2.5, 2.0) | 易混淆点:2.0 是小数常量而非整数 |
字符常量 | 单引号包裹的单个内容(如 'A', ' ', '\t') | 必须且只能有一个字符: - '11' 无效(两个字符); - ' ' 有效(空格算一个字符) |
字符串常量 | 双引号包裹的任意内容(如 "Hello", "") | 空字符串 "" 是有效数据,与 null 不同 |
布尔常量 | 仅 true/false(不加引号) | 易错点:"true" 是字符串而非布尔值 |
空常量(null) | 表示数据不存在(如 null) | 与空字符串区别: - null:数据不存在; - "":数据存在但内容为空 |
5.常量使用
知识点 | 核心内容 | 重点 |
常量使用 | 常量定义与分类 | 常量在程序中的不变性 |
整数常量 | 输出整数常量示例(-1) | 整数常量的正负性 |
小数常量 | 输出小数常量示例(1.5,1.0) | 小数点后即使为零也算小数常量 |
字符常量 | 单引号中必须有且只能有一个内容 | 单引号中多个字符会报错 |
- 空格作为字符常量 | 空格也算一个字符内容 | 与多个空格区分(不算字符常量) |
- Tab键作为字符常量 | Tab键算一个字符内容 | 与四个空格的区分 |
字符串常量 | 双引号中可以包含任意字符 | 空字符串也是合法的 |
布尔常量 | true和false为布尔常量 | 布尔常量与字符串的区别 |
空常量 | 空常量代表数据不存在 | 空常量不能直接输出使用 |
6.变量定义与使用
知识点 | 核心内容 | 重点 |
byte类型 | byte num1 = 100; 取值范围限制(-128~127) | 超出范围会编译报错,如byte num1 = 1000; |
short类型 | short num2 = 1000; 可重新赋值num2 = 1001; | 变量值可动态修改,体现"变量"特性 |
int类型 | int num3 = 10000; 默认整数类型(±21亿范围) | 直接输出变量名即可显示存储的值 |
long类型 | long num4 = 10L; 需加后缀L/l | 必须加L/l后缀,涉及数据类型转换原理 |
float类型 | float num5 = 2.5f; 需加后缀F/f | 必须加F/f后缀,与double区别 |
double类型 | double num6 = 2.5; 默认小数类型 | 无需后缀,直接赋值小数 |
char类型 | char num7 = 'a'; 单引号单字符 | 必须单引号且只能一个字符 |
boolean类型 | boolean num8 = true; 可重新赋值num8 = num9; | 变量值传递机制(引用关系) |
String类型 | String name = "金莲"; 双引号字符串 | 属于引用类型但定义格式类似基本类型 |
7.转义字符
知识点 | 核心内容 | 重点 |
转义字符定义 | 反斜杠在定义变量时代表转义字符,可转换字符含义 | 区分普通字符与转义字符的语法差异 |
转义字符功能 | 1. 将普通字符转为特殊含义字符; 2. 将特殊字符转为普通字符 | 反斜杠n与println的换行效果对比 |
常见转义符示例 | - \n换行符; - \t制表符(Tab键效果) | 记忆\n与\t的具体应用场景 |
路径表示问题 | 单反斜杠引发非法转义符错误,需用\\表示真实反斜杠 | 双反斜杠的转义原理理解 |
8.标识符
知识点 | 核心内容 | 重点 |
标识符定义 | 给类、方法、变量取的名字 | 区分标识符与关键字 |
硬性规定 | 1. 可包含:英文字母、数字、$、_; 2. 不能以数字开头; 3. 不能是关键字(如static、public) | 数字开头的错误示例:int 1I |
软性建议 | 1. 类名:大驼峰式(每个单词首字母大写); 2. 方法/变量名:小驼峰式(首单词小写,后续单词首字母大写); 3. 见名知意,禁用中文 | 类名示例:Demo08; 变量名示例:publicStatic |
关键字冲突 | 避免使用Java预定义关键字(如static、public) | 组合非关键字可用(如publicStatic) |
9.强转注意事项
知识点 | 核心内容 | 重点 |
byte/short类型自动转换 | 当使用整数常量赋值且不超出范围时,JVM会自动强转 | 常量赋值无需手动强转 vs 变量参与需手动强转 |
类型提升规则 | byte/short运算时自动提升为int型 | b=b+1会报错需强制转换 |
char类型运算特性 | 参与运算时自动提升为int型 | 会查询ASCII/Unicode码表转换 |
ASCII码表应用 | 英文字符对应整数值查询表 | 字符'0'=48/'A'=65/'a'=97的规律 |
Unicode码表扩展 | 处理ASCII范围外的字符(如中文) | 汉字"中"=20013的编码原理 |
强制转换语法 | (byte)(b+1)的括号使用技巧 | 整体表达式转换 vs 局部变量转换 |
模块三
10.idea常用快捷键
知识点 | 核心内容 | 重点 |
常用快捷键 | Alt+回车:导入包及自动修正代码 | 快捷键的使用和自动修正功能 |
自动修正代码示例 | int I = 2.5报错,Alt+回车选择cast to int修复 | 强制类型转换的自动修复 |
变量重名问题 | 在同一作用域内不能定义重名变量 | 变量命名规则和错误处理 |
无变量接收值问题 | 直接写100会报错,Alt+回车自动生成变量接收 | 变量定义和错误处理 |
导包操作 | 使用Scanner类需要导包,Alt+回车自动导包 | 类的导入和包管理 |
删除行快捷键 | Ctrl+Y:删除光标所在行 | 快捷键的使用和代码编辑效率 |
复制当前行 | Ctrl+D:复制当前行代码 | 快捷键的使用和代码编辑效率 |
格式化代码 | Ctrl+Alt+L:格式化代码 | 代码格式化和可读性提升 |
单行注释 | Ctrl+/:单行注释 | 注释的使用和代码管理 |
多行注释 | Ctrl+Shift+/:多行注释 | 注释的使用和代码管理 |
移动当前行 | Alt+Shift+上下箭头:移动当前行代码 | 代码编辑和重构效率 |
自动生成变量 | 先写等号右边,Alt+回车选择introduce local variable生成左边变量 | 变量定义和代码自动化 |
11.赋值运算符
知识点 | 核心内容 | 重点 |
基本赋值运算符 | 使用等号(=)进行赋值操作,先计算右边表达式再将结果赋给左边变量 | 必须区分赋值方向(右→左)与数学等号的区别 |
复合赋值运算符 | 包含+=、-=、*=、/=、%=等组合运算符 | b += 1与b = b + 1不等价(前者自动类型转换) |
类型转换规则 | 变量参与运算时自动提升为int型,常量赋值不超范围则无需转换 | byte/short运算必须手动强转,复合运算符例外 |
复合运算符特性 | 虚拟机对+=等操作自动处理类型转换,无需显式强转 | 实际开发中优先使用复合运算符简化代码 |
12.与或运算符
知识点 | 核心内容 | 易混淆点 | 代码验证示例 |
单与(&)运算符 | 1. 布尔型运算:有假则假; 2. 数字型运算:按位与; 3. 无短路效果(前为假仍执行后面判断) | 与双与的短路效果区别 | int a=10,b=20; boolean r=(++a>100) & (++b>10);; 结果:a=11,b=21 |
双与(&&)运算符 | 1. 布尔型运算:有假则假; 2. 有短路效果(前为假则跳过后面判断) | 不能用于数字位运算 | int a=10,b=20; boolean r=(++a>100) && (++b>10);; 结果:a=11,b=20 |
单或(|)运算符 | 1. 布尔型运算:有真则真; 2. 数字型运算:按位或; 3. 无短路效果(前为真仍执行后面判断) | 与双或的短路效果区别 | int a=10,b=20; boolean r=(++a<100) | (++b>10);; 结果:a=11,b=21 |
双或(||)运算符 | 1. 布尔型运算:有真则真; 2. 有短路效果(前为真则跳过后面判断) | 不能用于数字位运算 | int a=10,b=20; boolean r=(++a<100) || (++b>10);; 结果:a=11,b=20 |
数值区间判断 | 正确写法:i>=1 && i<=100; 错误写法:1<=i<=100(数学表达式不适用) | Java语法与数学表达式的区别 | int i=50; boolean inRange=(i>=1 && i<=100); |
模块四
13.Scanner类的next()方法和nextLine()方法
知识点 | 核心内容 | 重点 |
Scanner类的next()方法 | 用于录入字符串,遇到空格或回车即结束录入 | 空格会截断输入,只接收空格前的部分 |
Scanner类的nextLine()方法 | 用于录入字符串,仅遇到回车才结束录入 | 可接收包含空格的完整字符串 |
next()与nextLine()混合使用问题 | 连续使用时nextLine()会接收next()遗留的空格及后续内容 | 看似跳过输入,实际是接收了残留数据 |
数据类型匹配异常 | nextInt()等类型方法要求输入匹配的数据类型 | 输入非整数字符会抛出InputMismatchException |
14.Random随机数
知识点 | 核心内容 | 重点 |
Random类的基本使用 | 导包→创建对象→调用方法(nextInt()) | 默认范围:int全范围随机;指定范围:nextInt(n)生成0到n-1的随机数 |
指定范围的随机数生成 | 通过数学运算调整范围(如nextInt(10)+1生成1-10) | 易错点:范围边界计算(如100-999需nextInt(900)+100) |
Random的底层机制 | 每次运行重新生成随机数,结果不可预测 | 对比:与固定种子(new Random(seed))的确定性差异 |
常见应用场景 | 抽奖、验证码、游戏数值等需随机结果的场景 | 注意:范围逻辑需严格验证(如1-100≠nextInt(100)) |
15.switch case
知识点 | 核心内容 | 重点 |
switch语句的break作用 | break用于结束当前case语句,防止执行后续case | 忘记写break会导致case穿透 |
case穿透现象 | 当case后没有break时,程序会继续执行后续case直到遇到break或switch结束 | 穿透会执行多个case代码块 |
穿透性应用场景 | 利用穿透特性简化多条件同结果代码(如12/1/2月都输出冬季) | 需明确何时需要/不需要break |
月份季节判断案例 | 通过穿透性优化代码结构: - 冬季(12/1/2月); - 春季(3/4/5月); - 夏季(6/7/8月); - 秋季(9/10/11月) | default处理非法输入 |
Scanner输入应用 | 配合switch实现动态输入验证: Scanner.nextInt()获取用户输入 | 输入类型需与case匹配 |
16.if与switch的区别
知识点 | 核心内容 | 重点 |
if与switch的区别 | if从上到下逐个条件判断;switch直接跳转匹配的case | 执行流程差异(if顺序判断 vs switch精准跳转) |
if的灵活性 | 支持复杂条件逻辑(如范围判断、组合条件) | 实际开发中if使用更频繁 |
switch的效率特性 | 基于单一值快速匹配,适合离散值枚举 | break的作用(防止case穿透) |
debug工具应用 | 通过调试观察代码执行流程 | 断点调试演示if/switch差异 |
17.do-while循环
知识点 | 核心内容 | 重点 |
do-while循环 | 先执行循环体再判断条件,至少循环一次 | 与while/for循环的区别:执行顺序差异(先循环后判断) |
语法结构 | do {循环语句; 步进表达式;} while(比较条件); | 大括号位置、分号结尾易遗漏 |
执行流程 | 1. 初始化变量→2. 执行循环体→3. 步进表达式→4. 条件判断→重复2-4直到false | 强制首轮执行的特性 |
适用场景 | 需至少执行一次的场景(如输入校验、菜单交互) | 开发中使用频率较低 |
模块五
18.数组
知识点 | 核心内容 | 重点 |
数组长度获取 | 使用数组名.length语法(不带括号) | length是属性不是方法,区别于nextInt()等带括号的方法调用 |
数组索引概念 | 元素在数组中的存储位置/编号(从0开始) | 最大索引=数组长度-1,索引具有唯一性 |
数组操作原理 | 所有存取查操作都需通过索引完成 | 类比旅店房间号机制(零基编号系统) |
字符串数组示例 | String[] arr = {"迪迦奥特曼","猫和老鼠","海绵宝宝"} | 静态初始化语法与索引对应关系(0=迪迦) |
长度属性验证 | int len = arr.length;输出元素数量 | 属性与方法语法差异(无参vs带括号) |
19.数组获取数据
知识点 | 核心内容 | 重点 |
数组元素获取方法 | 通过索引值获取元素(数组名[索引]),直接输出数组名会返回内存地址值 | 地址值 vs 元素值; 直接输出数组名返回的是地址值而非元素内容 |
数组内存机制 | 数组在内存中分配地址值(唯一标识),通过地址值可定位并操作数组 | 地址值的本质; 内存中的"身份证号",用于唯一标识数组 |
默认值规则 | 未赋值的数组元素存在默认值: - 整数:0; - 小数:0.0; - 字符:\u0000; - 布尔:false; - 引用类型:null | 动态初始化未赋值的陷阱; 系统自动赋予默认值而非"空" |
存取操作规范 | 存值需赋值(arr[0]=1),取值直接引用索引(System.out.println(arr[0])) | 操作符混淆风险; 存取语法相似但等号是关键区分点 |
20.数组扩容
知识点 | 核心内容 | 重点 |
数组扩容原理 | 通过创建新数组并复制原数组元素实现扩容,原数组引用指向新数组地址 | 数组定长特性 vs 扩容逻辑(地址值覆盖) |
内存地址机制 | 数组变量存储的是内存地址值,通过赋值操作可改变引用指向 | 地址值传递与原始数组的关系 |
代码实现步骤 | 1. 创建新数组; 2. 复制元素; 3. 地址值覆盖(oldArr = newArr) | 元素复制范围控制(避免越界) |
默认值规则 | 扩容后新增位置自动填充默认值(如int数组为0) | 未显式赋值的元素状态 |
21.内存划分
知识点 | 核心内容 | 重点 |
内存划分 | JAVA将内存划分为五部分:栈(Stack)、堆(Heap)、方法区(Method Area)、本地方法栈(Native Method Stack)、寄存器(PC Register) | 重点掌握前三部分(栈、堆、方法区) |
栈内存(Stack) | 存储方法运行时的数据(如局部变量),方法执行时入栈,执行完毕弹栈释放内存 | 方法未及时弹栈会导致栈内存溢出 |
堆内存(Heap) | 存储对象和数组,new操作在堆中开辟空间并分配地址值,数据有默认值(如int=0、boolean=false) | 地址值的作用(通过变量引用堆中对象) |
方法区(Method Area) | 代码预备区,存储类信息和方法信息(如.class文件内容) | 与栈/堆的协作关系(代码加载→方法区→运行时分配) |
本地方法栈 | 运行Native方法(如C语言编写的底层功能,扩展JAVA能力) | 与硬件交互的场景(如IO流读写硬盘) |
内存协作流程 | 示例: int[] arr = new int[3]; 1. .class加载到方法区; 2. main方法入栈运行; 3. new在堆中开辟数组空间(含默认值); 4. 变量arr保存堆内存地址 | 地址指向的实际意义(变量通过地址操作堆内对象) |
22.二维数组
知识点 | 核心内容 | 重点 |
二维数组定义 | 使用两个中括号表示二维数组,本质是"数组套数组" | 动态初始化与静态初始化的语法区别 |
动态初始化语法 | 数据类型[][] 数组名 = new 数据类型[m][n]; 三种变体:中括号前置/后置/分开放置 | m代表二维数组长度(包含的一维数组数量); n代表每个一维数组的长度 |
特殊动态初始化 | new 数据类型[m][]形式表示一维数组未被创建; 未创建的一维数组默认值为null | 与带n声明的区别:后者已创建但元素为默认值 |
静态初始化 | 直接赋值:数据类型[][] 数组名 = {{元素1,元素2},{...}}; 支持简化写法省略new关键字 | 各一维数组长度可不一致; 与动态初始化固定长度的区别 |
内存结构示例 | 图示说明new int[2][3]和new int[2][]的内存分配差异 | null与默认值的内存状态区别 |
典型应用场景 | 不规则二维数组案例: {{"孙悟空","唐僧"},{"刘备","关羽","张飞"}} | 静态初始化更适合非对称数据结构 |
模块六
23.方法定义
知识点 | 核心内容 | 重点 |
方法定义通用格式 | 修饰符 + 返回值类型 + 方法名 + 参数 + 方法体 + return结果 | void与return的冲突(void方法不可return具体值) |
修饰符作用 | public static固定搭配(公共访问权限 + 静态方法) | 面向对象阶段会详细解释 |
返回值类型 | 由return结果的数据类型决定(如int/double/String) | 无返回值时需用void |
方法命名规范 | 小驼峰命名法(如getSum) | 需见名知意 |
参数定义 | 数据类型 + 变量名(多个参数用逗号隔开) | 调用时赋值,定义时不需初始化 |
方法体与return | 方法体为具体实现代码;return返回结果(仅非void方法可用) | 方法体操作参数生成返回值(类比“牛消化饲料产奶”) |
IDE分割线设置 | 勾选Show Method显示方法间分割线(解决代码混淆问题) | 路径:File → Settings → Editor → General → Appearance |
24.无参有返回值方法
知识点 | 核心内容 | 重点 |
无参有返回值方法的定义 | public static+返回值类型+方法名() {} | 返回值类型不能写void,方法体需包含return语句 |
返回值的处理 | 方法体内通过return语句返回结果 | 返回值类型需与方法体内返回的数据类型一致 |
方法调用的两种方式 | 直接调用和赋值调用 | 直接调用将结果直接输出,赋值调用将结果赋值给变量 |
打印调用(直接调用) | 调用方法后,将结果直接放入输出语句中 | 适用于不需要再次使用结果的情况 |
赋值调用 | 调用方法后,将结果赋值给一个变量 | 推荐方式,便于后续使用结果 |
执行流程 | 调用方法 -> 执行方法体 -> 返回结果 -> 接收结果 | 理解方法调用的整个过程,特别是返回值的接收 |
示例:整数相加方法 | public static int sum(int a, int b) { return a+b; } | 方法的定义、调用和返回值处理 |
25.方法_参数和返回值使用时机
知识点 | 核心内容 | 重点 |
参数的使用时机 | 当想将方法A的数据传递到方法B时,定义方法B需要带参数 | 参数传递的机制和目的 |
返回值的使用时机 | 调用方法A时,想要方法A的结果去参与其他的操作,方法A需要返回结果 | 返回值类型与接收 |
三层架构思想 | Controller层(接收请求回响应)、Service层(业务逻辑)、DAO层(持久层) | 各层职责与协作方式 |
参数在三层架构中的应用 | Ctrl层接收请求参数,通过参数传递到Service层,Service层再通过参数传递到DAO层 | 参数在各层之间的传递与接收 |
返回值在三层架构中的应用 | DAO层查询结果需要返回给Service层,Service层处理结果需要返回给Ctrl层 | 返回值的传递与接收,以及根据返回值做不同的响应 |
三层架构的框架对应 | Ctrl层对应Spring MVC,Service层对应Spring,DAO层对应MyBatis | SSM框架的组成与对应层次 |
26.方法注意事项
知识点 | 核心内容 | 重点 |
方法注意事项 | 方法不调用不执行;执行顺序仅与调用顺序相关;方法间不可嵌套 | void与return的共存规则 |
void与return的关系 | void表示无返回值,不可与return 结果共存,但可与return(无数据)共存 | return 结果会先返回数据再结束方法;return仅结束方法 |
方法中的return限制 | 一个方法不能连续写多个return(语法错误);if-else分支中的return需覆盖所有逻辑路径 | 多返回值需用数组封装;未覆盖分支的return会报错 |
方法调用前提 | 调用方法前需确认方法已定义,否则报错 | 常见错误:未定义直接调用 |
27.方法调用技巧
知识点 | 核心内容 | 重点 |
方法定义与调用 | 先定义后调用,避免报错 | 定义顺序错误导致报错 |
返回值处理 | 无返回值方法在方法内输出;有返回值方法需用变量接收后输出 | 返回值类型与接收变量不匹配 |
方法调用方式 | 直接调用(无返回值)、打印调用(不推荐)、赋值调用(推荐) | 混淆调用方式适用场景 |
28.方法重载
知识点 | 核心内容 | 重点 |
方法重载的判断标准 | 方法名相同且参数列表不同(类型/顺序/数量) | 与返回值类型、参数名称无关 |
重载方法调用冲突 | 当参数类型存在隐式转换时可能导致调用歧义(如int和double) | sum(10, 2.5)可能同时匹配多个重载 |
典型重载场景 | 相同功能不同实现细节(如集合的add()方法) | 位置添加 vs 末尾添加属于合法重载 |
非法重载示例 | 仅修改参数名(int a vs int x)或返回值类型 | 编译器报错:"method is already defined" |
合法重载变体 | 无参/有参、类型顺序不同((int,double) vs (double,int)) | 方法签名实质不同即可 |
方法签名唯一性 | 严格区分大小写(Open()与open()不算重载) | 视为完全独立的方法 |
模块七
29.面向对象思想
知识点 | 核心内容 | 重点 |
面向对象思想 | 核心编程思想,强调“调用他人功能”而非亲力亲为(如洗衣机洗衣服、外卖点餐等类比) | 与面向过程的区别(C语言 vs Java); 关键判断标准:是否调用其他类的成员 |
类与对象 | 类(Class)是模板,对象是实例(如Scanner/Random的new操作) | new对象后通过.调用方法; 特殊场景:静态方法(static)可直接类名调用(如Arrays.toString()) |
匿名对象 | 一次性使用的对象(未赋变量名) | 内存效率 vs 代码可读性权衡 |
对象内存解析 | 堆栈内存分配机制(对象在堆,引用在栈) | 易混淆点:基本类型 vs 引用类型的存储差异 |
成员变量与局部变量 | 作用域与生命周期对比(类内全局 vs 方法内临时) | 默认值差异:成员变量自动初始化,局部变量需手动赋值 |
面向对象应用场景 | 调用他人功能时使用(如Scanner.nextInt()、Random.nextInt()) | 典型误区:自身类内方法调用不属面向对象 |
代码简化案例 | Arrays.toString(arr) vs 手动遍历拼接字符串 | 效率对比:面向对象减少重复代码量 |
30.对象的使用
知识点 | 核心内容 | 重点 |
类与对象概念 | 类是一类事物的抽象表示形式,对象是类的具体实例 | 抽象vs具体体现的辩证关系 |
对象创建三步法 | 1. 导包 2. 创建对象 3. 调用成员 | 同包下免导包规则与java.lang包特殊性 |
对象成员调用 | 对象名.成员变量 / 对象名.方法() | 方法调用的四种组合形式(有参无参/有返回值无返回值) |
默认值机制 | 未赋值的成员变量自动初始化(如String=null, int=0) | 默认值陷阱在业务逻辑中的影响 |
面向对象基础语法 | 类名 对象名 = new 类名()标准创建格式 | 对象名命名规范与内存指向原理 |
包访问规则 | 同包类直接互访 vs 跨包需导包 | import语句的精确导入与通配符导入区别 |
31.匿名对象
知识点 | 核心内容 | 重点 |
匿名对象的使用 | 匿名对象即没有变量名直接使用的对象,通过new关键字直接创建并调用方法或访问成员变量 | 匿名对象适用于一次性调用方法,不适用于需要多次访问或修改对象状态的场景 |
原始方式与匿名对象的对比 | 原始方式:使用变量接收对象,可以多次访问和修改对象状态;匿名对象方式:直接创建并使用对象,无法后续访问或修改 | 易混淆点:匿名对象无法保存状态,每次使用都会创建新的对象实例 |
匿名对象的适用场景 | 适用于只需要调用对象方法,不需要保存对象状态的场景,如调用工具类的方法 | 误用匿名对象进行赋值操作,会导致无法后续访问或修改该值 |
原始方式的优势 | 可以保存对象状态,方便后续访问和修改,适用于需要多次使用对象的场景 | |
堆栈内存分析 | 原始方式中,对象存储在堆内存中,变量名保存在栈内存中,通过变量名可以访问堆内存中的对象;匿名对象只存在于堆内存中,无法通过变量名访问 | 理解堆栈内存模型对于掌握对象存储和访问机制至关重要 |
32.两个对象指向同一片空间
知识点 | 核心内容 | 重点 |
对象内存分配原理 | 两个对象变量指向同一内存空间时的数据共享机制 | 地址值传递导致的对象关联性 |
引用类型变量赋值 | 通过Phone p2 = p1实现对象引用传递 | 直接赋值与new创建的本质区别 |
堆栈内存交互 | 栈内存存储引用地址,堆内存存储实际对象数据 | 方法区存储类模板的class对象 |
对象属性修改影响 | 通过任一引用修改属性会同步影响所有关联对象 | 多引用操作同一对象的副作用 |
内存图绘制方法 | 三区域划分(栈/堆/方法区)与地址指向关系 | 数组与对象内存模型的相似性 |
33.成员变量和局部变量
知识点 | 核心内容 | 重点 |
成员变量 vs 局部变量 | 定义位置不同:成员变量在类中方法外,局部变量在方法内或参数位置 | 初始化值差异:成员变量有默认值,局部变量需手动赋值 |
作用范围不同:成员变量作用于整个类,局部变量仅限所在方法 | 内存位置:成员变量在堆中,局部变量在栈中(非重点) | |
生命周期不同:成员变量随对象创建/销毁,局部变量随方法调用/结束(非重点) | ||
成员变量默认值规则 | 未手动赋值时,成员变量自动赋予默认值(如String为null) | 易错点:局部变量未赋值直接使用会报错 |
作用域验证示例 | Person类中name(成员变量)可在所有方法调用,而方法内变量(如i)仅限本方法 | 混淆点:误将局部变量跨方法调用 |
模块八
34.封装 private
知识点 | 核心内容 | 重点 |
封装的概念 | 将代码片段放入方法中隐藏实现细节,对外提供公共接口(方法名)调用 | 区分“代码封装”与“属性封装”的异同 |
private关键字 | 私有化修饰成员变量/方法,限制仅本类访问,强制通过公共接口间接操作 | 不合理赋值问题(如年龄赋负值)的解决方案 |
封装的实际应用 | 1. 方法封装代码逻辑; 2. private封装属性+公共setter/getter控制赋值逻辑 | setter方法中加入有效性校验(如if(age>0)) |
封装的优势 | 1. 隐藏实现细节; 2. 增强数据安全性; 3. 降低耦合度 | 对比public与private的访问权限差异 |
案例演示 | 1. 数组打印方法封装; 2. Person类属性私有化+setAge校验 | 易错点:忘记提供公共访问接口导致数据无法操作 |
35.get set方法
知识点 | 核心内容 | 重点 |
封装思想 | 使用private隐藏属性细节,通过get/set方法提供公共访问接口 | 私有化属性后仍需通过方法控制赋值有效性(如setAge中校验负值) |
get/set方法作用 | set用于属性赋值(可加入逻辑校验),get用于属性取值 | 方法内可直接访问本类私有成员(与外部调用区别) |
封装实现流程 | 1. 属性私有化 → 2. 编写带校验的set方法 → 3. 编写get方法 → 4. 外部通过方法间接访问 | 校验逻辑需覆盖边界值(如年龄>150) |
封装优势 | 防止不合理赋值(如age=-18)、隐藏实现细节、统一访问入口 | private限制的是外部直接访问而非本类内部访问 |
36.this关键字
知识点 | 核心内容 | 重点 |
this关键字基本使用 | 通过this区分重名成员变量与局部变量,遵循就近原则(默认访问局部变量) | 成员变量与局部变量重名时的访问优先级 |
this代表当前对象 | this指向调用该方法的对象,通过输出对象地址值验证(person与person2调用时this指向不同) | 动态绑定机制:this具体指向由调用对象决定 |
标准get/set方法改造 | 形参与成员变量同名时,用this.变量名明确赋值目标(如this.name = name) | 未用this会导致局部变量自赋值(age=age无效) |
代码示例分析 | speak()方法中this.name输出成员变量,name输出局部变量(传参"刘彦昌") | 输出结果差异:this.name为"沉香",name为"刘彦昌" |
对象调用验证 | person.speak()与person2.speak()中this分别指向不同对象地址 | 通过分割线对比两对象地址值及this指向 |
37.构造方法
知识点 | 核心内容 | 重点 |
构造方法定义 | 方法名与类名一致,用于初始化对象,无返回值(连void也不写) | 易混淆:new 类名()实际调用的是构造方法,而非创建类本身 |
构造方法分类 | 无参构造(默认存在,虚拟机自动提供)、有参构造(为属性赋值)、满参构造(为所有属性赋值) | 重点:默认无参构造在类中未显式定义时仍存在 |
无参构造特点 | 格式:public 类名(){};作用:仅用于new对象 | 易错点:手动定义后,默认无参构造失效 |
构造方法调用 | 通过new关键字隐式调用(无需对象.操作) | 示例:Person p = new Person();直接触发无参构造执行 |
IDEA快捷操作 | 自动生成get/set方法和构造方法(如Alt+Insert) |
知识点 | 核心内容 | 考试重点/易混淆点 |
有参构造 | 定义格式:public 类名(参数列表){为属性赋值} | 与无参构造的区别、如何为属性赋值 |
作用:创建对象的同时为属性赋值 | 有参构造与set方法的区别 | |
写法示例:public Person(String name, int age){this.name=name; this.age=age;} | 构造方法重载(参数列表不同) | |
注意:手写有参构造后,无参构造需手动添加 | 虚拟机默认提供无参构造,手写有参后不再自动提供 | |
属性赋值 | 通过有参构造、set方法为属性赋值 | 私有属性如何通过有参构造和set方法赋值 |
方法调用 | 按住Ctrl键,鼠标点击方法名可快速定位到方法定义 | 如何快速找到调用的方法 |
get/set方法 | get方法用于获取属性值,set方法用于设置属性值 | get/set方法的作用、使用场景 |
构造方法重载 | 多个构造方法,参数列表不同 | 构造方法重载的意义、如何实现 |
38.JavaBean
知识点 | 核心内容 | 重点 |
Java Bean定义 | 符合特定规范的Java类: 1. 公共类(public class); 2. 提供无参/有参构造方法; 3. 成员变量私有化; 4. 提供get/set方法 | 易混淆点: - 非私有属性也可提供get/set,但无实际意义 |
分层架构与分包 | 开发时按功能分包: - controller(表现层); - service(业务层); - dao(持久层); - pojo(存放Java Bean); - util(工具类) | 重点: - 包名规范(公司域名倒写); - 类的职责隔离 |
Java Bean使用场景 | 1. 通过set方法或有参构造赋值; 2. 通过get方法取值; 3. 实体类统一存放于pojo包 | 易错点: - 无参构造方法体通常为空 |
39.javabean参与添加功能
知识点 | 核心内容 | 易混淆点/关键细节 | 参与环节 |
三层架构 | 表现层(Controller)、业务层(Service)、持久层(DAO)的分工 | 表现层仅处理请求/响应,业务逻辑应集中在Service层 | 整体框架设计 |
注册功能流程 | 1. 页面输入 → 2. Controller获取参数 → 3. 封装为JavaBean → 4. 逐层传递至DAO → 5. 数据库操作 | 参数封装必要性(避免多参数传递混乱) | 功能实现核心链路 |
JavaBean作用 | 数据打包(如User对象含ID、用户名、密码)、跨层传输、属性提取(get/set方法) | 与DTO/VO的区别(本例未涉及分层模型) | 数据封装与传递 |
DAO层逻辑 | 1. 用户名查重 → 2. 无重复则插入数据 | 查询与插入的原子性 | 数据库交互 |
响应控制 | Controller根据Service返回结果(如1/0)动态响应页面 | 状态码设计(可扩展为枚举/常量) | 结果反馈 |
模块九
40.static关键字
知识点 | 核心内容 | 重点 |
static关键字 | 用于修饰成员变量和方法,使成员属于类而非对象,实现数据共享 | 静态成员与非静态成员的内存加载顺序(静态优先) |
静态成员特点 | 1. 类加载时即存在; 2. 通过类名直接调用; 3. 所有对象共享同一静态成员 | 区分类名.静态成员与对象.非静态成员的调用方式 |
应用场景 | 解决多对象共享属性问题(如班级换教室只需修改一次静态变量) | 静态方法中不可直接调用非静态成员(需先实例化对象) |
内存机制 | 静态成员存储在方法区,非静态成员存储在堆内存对象中 | 易混淆:静态成员生命周期与类相同,非静态成员与对象绑定 |
代码示例 | static String classroom = "111";; 修改时:Student.classroom = "222"; | 需注意静态变量初始化的线程安全问题 |
41.static内存说明
知识点 | 核心内容 | 重点 |
static成员的内存存储位置 | 静态成员存储在静态域中,静态域在JDK 6时位于方法区(永久代),JDK 7开始移至堆内存 | 方法区 vs. 堆内存:JDK 7后静态域迁移至堆,目的是提高内存回收效率 |
方法区的演变 | JDK 6称“永久代”,JDK 8改为“元空间”,但均为方法区的具体实现 | 永久代、元空间与方法区的关系:需明确三者是同一逻辑区域的不同实现 |
静态域迁移原因 | 堆内存回收效率高,方法区回收效率低;迁移后可及时释放静态成员占用的内存 | 为什么静态域不留在方法区?:避免内存长期占用,优化运行性能 |
静态成员共享机制 | 静态成员随类加载而加载,被该类的所有对象共享;不属于对象成员,仅属于类 | 静态成员访问方式:直接通过类名调用(如Student.classroom),无需实例化对象 |
内存模型示例(Student类) | classroom(静态)存储在堆的静态区,name(实例)存储在对象堆内存;新建对象共享静态成员 | 对象与静态区的关系:对象通过内存地址共享静态成员,但静态成员生命周期独立于对象 |
42.静态成员访问特点
知识点 | 核心内容 | 重点 |
静态方法访问非静态成员 | 静态方法中不能直接访问非静态成员,需通过new对象调用 | 先出生的静态成员无法直接访问后出生的非静态成员(类比秦始皇不知康熙存在) |
非静态方法访问静态成员 | 非静态方法中能直接访问静态成员(同类可直接调用/类名调用,不同类需类名调用) | 反编译证明即使通过对象调用静态方法,底层仍是类名调用 |
静态方法访问静态成员 | 静态方法中能直接访问静态成员(同类可直接调用,不同类需类名调用) | 同类访问时存在两种调用方式(直接调用/类名调用) |
非静态方法访问非静态成员 | 非静态方法中能直接访问非静态成员(同类直接调用,不同类需new对象调用) | 同类访问时new对象调用非必要但可行 |
通用访问规则总结 | 非静态成员始终通过new对象调用;静态成员始终推荐类名调用 | 静态成员生命周期早于非静态成员(类加载vs对象实例化) |
43.静态成员的使用场景
知识点 | 核心内容 | 重点 |
静态成员的使用场景 | 静态成员通过类名直接调用,无需实例化,适用于工具类等场景 | 静态成员与实例成员的区别(内存加载时机) |
静态成员的局限性 | 所有静态成员会在类加载时占用内存,滥用会导致内存浪费 | 需权衡“便利性”与“资源占用” |
工具类设计规范 | 1. 成员全静态化; 2. 构造方法私有化(禁止实例化); 3. 功能需高频复用(如数组求最大值) | 工具类与普通类的设计差异 |
代码复用案例 | 抽取ArrayUtils.getMax()方法,避免重复编写数组遍历逻辑 | 工具类方法的通用性设计(参数/返回值) |
44.可变参数
知识点 | 核心内容 | 注意事项 |
可变参数定义 | 使用数据类型...变量名语法定义(必须三个点) | 必须三个点,两个或四个点都不行 |
可变参数本质 | 底层实现是数组(可通过反编译验证) | 可使用数组遍历方式操作可变参数 |
参数位置规则 | 可变参数必须放在参数列表最后 | 报错提示:varargs parameter must be the last |
多参数共存 | 可与普通参数共存(如int i, int... arr) | 普通参数需在前,顺序不可颠倒 |
方法调用方式 | 可传入任意数量同类型参数(自动转为数组) | 类型必须匹配定义的数据类型 |
45.递归
知识点 | 核心内容 | 重点 |
递归的定义 | 方法内部调用自身的编程技巧 | 与循环的区别(出口条件的必要性) |
递归的经典案例 | "从前有座山"的无限循环故事 | 无出口的递归导致栈溢出错误 |
递归的分类 | 直接递归(方法A调A)和间接递归(方法A→B→C→A循环调用) | 间接递归的代码实现逻辑 |
递归的注意事项 | 必须设置终止条件(出口),且递归次数不宜过多 | 栈内存溢出的原理(StackOverflowError) |
递归的代码演示 | method()无限调用自身导致崩溃 | 实际开发中需通过条件判断控制递归深度 |
46.斐波那契数列
知识点 | 核心内容 | 重点 |
斐波那契数列定义 | 数列中每个数字是前两个数字之和(从1,1开始) | 起始项定义(通常为F(1)=1, F(2)=1) |
兔子繁殖模型 | 1.新生兔1个月成熟; 2.成熟后每月生1对; 3.无死亡假设 | 第二个月不生兔的时间延迟特性 |
递归算法实现 | method(n) = method(n-1) + method(n-2) | 终止条件必须包含n=1和n=2的情况 |
数列计算示例 | 月份:1→1对, 2→1对, 3→2对, 4→3对, 5→5对, 6→8对 | 第6个月结果8对的推导过程 |
递归调用过程 | 方法自调用时的参数传递机制(月份递减) | 递归树展开时的重复计算问题 |
47.数组反转
知识点 | 核心内容 | 重点 |
数组翻转算法 | 中心思想是数组对称索引位置上的元素互换,通过中间变量实现元素位置交换 | 确定交换终止条件(min >= max)和索引移动规则(min++/max--) |
索引对称原理 | 奇数数组中间元素自对称,偶数数组全部成对交换(图示[1,2,3,4,5,6,7]与[7,6,5,4,3,2,1]索引对应关系) | 奇偶数组的不同处理逻辑 |
元素交换技术 | 使用临时变量temp的三步交换法: 1. temp = arr[min]; 2. arr[min] = arr[max]; 3. arr[max] = temp | 类比水杯交换的具象化理解 |
循环控制逻辑 | for(int min=0,max=arr.length-1; min<max; min++,max--) 复合循环条件写法 | 多语句初始化/迭代的语法特性 |
边界条件处理 | 循环终止条件min < max同时覆盖奇偶两种情况 | 避免偶数数组重复交换 |
48.冒泡排序
知识点 | 核心内容 | 重点 |
冒泡排序定义 | 数组排序方法,通过相邻元素比较和交换实现排序 | 默认升序排序,需理解“相邻元素”指 arr[i] 和 arr[i+1] |
排序过程 | 1. 每轮将最大值“冒泡”到末尾; 2. 比较轮数=数组长度-1,每轮比较次数递减 | 易错点:忽略每轮减少一次比较(已排序部分无需重复比较) |
代码实现关键 | 1. 双重循环(外层控制轮数,内层控制比较次数); 2. 相邻元素交换条件 arr[i] > arr[i+1] | 笔试高频:需默写代码框架及边界条件(如 i < arr.length-1) |
性能特点 | 时间复杂度 O(n²),空间复杂度 O(1) | 对比其他排序:效率低但实现简单,适合小规模数据 |
实例演示 | 数组 [5,4,3,2,1] 的完整排序步骤(4轮比较,每轮次数递减) | 重点观察:最大值如何逐步移动到末尾 |
49.二分查找
知识点 | 核心内容 | 重点 |
二分查找原理 | 通过不断折半缩小查找范围,提升查询效率 | 必须保证数组有序(升序/降序) |
中间索引计算 | mid = (min + max) // 2,动态调整min/max | 初始min=0,max=长度-1,非固定长度/2 |
查找流程 | 1. 比较目标值与mid元素; 2. 大于则min=mid+1; 3. 小于则max=mid-1; 4. 等于则命中 | 终止条件:min > max时未找到 |
效率对比 | 原始遍历:O(n); 二分查找:O(log n) | 数据量越大优势越显著(例:100数据仅需7次比较) |
边界案例 | 目标值在首尾/不存在时索引移动逻辑 | min/max更新需严格±1,避免死循环 |
50.对象数组
知识点 | 核心内容 | 重点 |
对象数组定义 | Person[]数组存储Person对象,数组定义语法与基本类型数组类似 | 数组元素类型与对象类型的匹配关系 |
对象数组初始化 | 创建三个Person对象并存入数组,通过索引赋值 | 数组存储的是对象引用(地址值)而非对象本身 |
数组遍历与属性访问 | 使用for循环遍历数组,通过getter方法获取对象属性 | 遍历得到的是对象引用,需通过引用访问成员方法 |
内存模型解析 | 堆内存中数组元素存储对象引用示意图 | 引用传递与值传递的本质区别 |
类型系统应用 | 接收数组元素必须使用Person类型变量 | 编译期类型检查机制 |
51.对象数组应用
知识点 | 核心内容 | 重点 |
对象数组创建 | 创建Student类数组并初始化三个学生对象 Student[] students = new Student[3] | 匿名对象初始化方式 |
类定义规范 | 定义Student类包含私有属性(name/score)和标准方法(构造器/getter) | 无参/有参构造器同时存在的必要性 |
冒泡排序算法 | 通过嵌套循环实现对象数组排序 | 比较成绩但交换整个对象 |
对象属性访问 | 通过getter方法获取私有属性进行比较 | 直接访问私有属性会导致编译错误 |
数组遍历输出 | 排序后遍历数组输出学生信息 | 注意数组越界问题 |
52.基本类型做参数传递
知识点 | 核心内容 | 重点 |
基本数据类型与引用数据类型的区分 | 基本数据类型包括四类八种(byte、short、int、long、float、double、char、boolean),其余均为引用数据类型 | 如何快速区分:只需记住基本数据类型的范围,其余均为引用类型 |
方法参数传递(基本数据类型) | 基本数据类型作为方法参数传递时,传递的是值而非变量本身,方法内部的修改不影响原始变量 | 易混淆点:误认为方法内部修改会影响原变量值 |
方法调用与栈内存机制 | 方法执行时压栈,运行完毕后弹栈,局部变量仅作用于当前方法栈帧 | 关键理解:方法栈的独立性导致变量作用域隔离 |
53.引用类型作参数传递
知识点 | 核心内容 | 重点 |
引用数据类型作为方法参数传递 | 引用数据类型(如数组)作为参数传递时,传递的是地址值,而非值本身。 | 区分基本数据类型和引用数据类型的参数传递方式;理解为何引用数据类型的修改会影响到原数据。 |
数组在内存中的存储 | 数组在堆内存中存储,变量保存的是数组的地址值。 | 数组的内存分配和地址值的概念;数组如何通过地址值进行访问和修改。 |
方法调用与栈的压栈弹栈 | 方法调用时,会在栈中压栈运行;方法执行完毕后,会弹栈返回。 | 方法调用的栈机制;压栈与弹栈对变量值的影响。 |
方法间参数传递的影响 | 引用数据类型作为参数传递时,方法间的修改会相互影响。 | 引用传递导致的修改共享问题;如何理解并避免不必要的修改。 |
基本数据类型与引用数据类型的区别 | 基本数据类型传递的是值,引用数据类型传递的是地址值。 | 两者在参数传递、内存存储和修改影响上的区别。 |
54.命令行参数
知识点 | 核心内容 | 重点 |
命令行参数 | 指main方法中的String[] args参数,通过命令行或IDE配置传递实参 | 参数传递格式(空格分隔)、IDE配置入口位置 |
参数传递方式 | 1. 命令行运行:java 类名 参数1 参数2; 2. IDEA配置:Run → Edit Configurations → Program Arguments | 参数与类名需空格分隔,参数按顺序对应数组元素 |
实际应用场景 | 临时测试方法功能(如method(String s1, String s2)),避免启动完整项目流程 | 与直接调用方法的区别(灵活性 vs 便捷性) |
IDE操作演示 | 1. 创建类并编写main方法; 2. 通过Edit Configurations设置参数(如哈哈 嘿嘿); 3. 运行后遍历args数组输出结果 | 配置路径易忽略(需通过类名旁箭头进入) |
55.快速生成方法
知识点 | 核心内容 | 重点 |
方法定义与调用顺序 | 初学者需先定义方法再调用,否则报错;熟练者可先调用后定义(通过IDE补全) | Alt+Enter快速生成方法(自动补全参数/返回值) |
IDE智能补全功能 | 使用Alt+Enter自动生成方法: - 无参无返回值(默认private修饰); - 有参无返回值(自动匹配参数类型); - 有返回值(自动推断类型) | 修饰符需手动调整 |
代码抽取为方法 | 选中代码块后按Ctrl+Alt+M快速抽取: - 自动识别依赖变量(如数组参数); - 支持修改方法名/修饰符; - 智能提示返回值需求 | 未选中变量时自动补全参数 |
IDE操作效率技巧 | - 通过快捷键生成代码结构; - 抽取重复逻辑为独立方法 | 需熟悉Alt+Enter与Ctrl+Alt+M组合键 |
56.debug调试
知识点 | 核心内容 | 重点 |
Debug调试概述 | 调试代码的手段,用于监测变量变化和定位错误 | 理解断点作用与调试模式启动方式 |
断点设置 | 在代码行左侧点击添加红色圆点(断点),右键选择Debug启动调试 | 断点可多位置设置,点击消失的特性易忽略 |
调试面板功能 | - 下一步(逐行执行); - 进入方法(跳转至被调用方法内部); - 跳出方法(返回调用处); - 放行(执行当前请求代码但不退出调试); - 结束调试(完全退出) | 放行 vs 结束调试的功能差异(是否保留调试模式) |
变量监控 | 调试过程中实时显示变量值变化(如数组索引赋值过程) | 通过变量面板观察I=3时的数组越界问题 |
调试应用场景 | 示例:购物车功能调试(addCart方法逐行检查变量) | 结合循环调用演示放行按钮的多次触发特性 |