自考04747 Java程序设计笔记:面向对象、异常处理与集合框架实战解析
1. 项目概述为什么需要一份“活”的笔记如果你正在自考计算机科学与技术专业并且被《Java语言程序设计一》这门课程课程代码04747所困扰那么你大概率已经搜罗过各种资料了。网上能找到的要么是零散的知识点罗列要么是厚重的教材扫描件再不然就是一些语焉不详的“重点总结”。这些资料最大的问题在于它们是“死”的。它们无法告诉你一个概念在真实的编程场景中如何运用一个语法点为什么会设计成这样以及在自考的试卷上它最可能以什么形式来考察你。我当初备考时深感于此。因此我决定不再被动地收集资料而是主动创造一份属于自考生的、带有“工程师思维”的笔记。这份笔记的目的不仅仅是帮你通过考试更是试图在你脑中搭建起Java编程最基础、最坚实的那部分框架。它融合了教材的核心考点、历年真题的命题规律以及我作为一名开发者在实际工作中对Java基础最朴素的理解。它不是教材的替代品而是教材的“翻译器”和“实战指南”旨在把书本上抽象的定义转化为你可以理解、记忆乃至运用的具体知识。2. 笔记的核心设计思路与架构2.1 目标导向紧扣自考大纲与真题自考有其独特的命题逻辑。我的笔记首要原则就是“考什么记什么怎么考怎么练”。我会深入研究04747的考试大纲将知识点分解为“识记”、“领会”、“简单应用”和“综合应用”四个层级。笔记内容会明确标注每个知识点所属的层级让你清楚知道哪些需要背哪些需要理解哪些需要反复练习。例如对于“Java的垃圾回收机制”这个知识点识记要求你知道垃圾回收的概念和优点。领会需要理解垃圾回收的基本原理如引用计数、可达性分析。简单应用能写出促使垃圾回收的代码如System.gc()并理解其不保证立即执行。综合应用在分析一段存在内存泄漏嫌疑的代码时能指出问题所在。笔记的每个章节都会以这样的逻辑来组织确保你的复习火力始终集中在得分点上。2.2 三维学习法概念、代码、考题三位一体这是本笔记的核心方法论。任何一个重要知识点都会从三个维度展开概念精讲用最直白的语言解释专业术语。比如解释“多态”我不会只说“同一操作作用于不同对象产生不同行为”我会说“就像你家的遥控器同一个‘操作’按开机键电视会亮屏空调会启动音箱会播放音乐不同‘对象’产生不同‘行为’。在Java里你用父类的引用去调用一个被重写的方法实际执行的是子类的方法这就是多态。”代码实证紧接概念提供最精简、最具代表性的代码片段。代码有详细注释逐行说明其作用。更重要的是我会展示常见的错误写法并进行对比让你知道“坑”在哪里。// 正确示例方法重写与多态 class Animal { public void makeSound() { System.out.println(动物发出声音); } } class Dog extends Animal { Override // 注解明确表示这是重写编译器会检查 public void makeSound() { // 方法名、参数列表必须完全相同 System.out.println(汪汪汪); } } public class TestPolymorphism { public static void main(String[] args) { Animal myAnimal new Dog(); // 父类引用指向子类对象 myAnimal.makeSound(); // 输出汪汪汪 体现了多态 } }考题链接立即附上与此知识点相关的历年自考真题或模拟题。我会分析题干拆解答题步骤告诉你考官在这个点上想考察什么。例如在多态的代码后可能会链接一道选择题“下列关于Java多态的叙述中错误的是”并逐一分析每个选项。这种“看到概念 - 理解代码 - 应对考题”的闭环学习路径能极大提升学习效率和应试能力。2.3 工具与形式为何选择Markdown与Git我选择用Markdown来编写这份笔记并建议你也在类似工具如Typora、VS Code、思源笔记中查看和学习。原因如下结构清晰Markdown的标题层级# ## ###天然适合构建知识树方便你快速定位和梳理章节关系。专注内容排版简洁没有复杂格式干扰让你能全心投入知识本身。兼容性强可以轻松导出为PDF、HTML等多种格式方便打印或在平板、手机上阅读。更进一步我将笔记的版本管理托管在Git平台如Gitee。这不仅仅是备份更是一种学习理念的体现持续更新我会根据最新的考情、读者的反馈以及Java语言的微小变化不断更新笔记内容。你可以通过git pull轻松获取最新版。问题追踪如果你发现笔记中有错误或难以理解的地方可以直接提交Issue。这构建了一个动态的、共同维护的学习社区。版本回溯如果你觉得新版的某个改动不适合自己可以随时回退到之前的任何一个版本。注意使用Git需要一点简单的命令行或图形界面工具知识。笔记的开头会提供最简明的Git使用指南确保零基础的考生也能轻松上手。3. 核心章节内容解析与学习要点《Java语言程序设计一》的知识体系可以划分为几个核心模块。下面我将选取其中最容易混淆和最重要的部分展示我的笔记是如何进行拆解和讲解的。3.1 面向对象基础封装、继承、多态的精髓这是Java的基石也是自考的重中之重。很多考生能背下定义但一写代码或做题就错。3.1.1 封装不仅仅是private封装的核心是“隐藏细节暴露接口”。笔记中会强调为什么用private不是为了用而用是为了保护对象内部数据的一致性。例如一个Person类的age属性如果设为public外部就可以直接person.age -100;这显然不合理。通过private限制并提供setAge(int age)方法我们就可以在方法内加入逻辑判断if(age0 age150)。JavaBean规范这是封装的具体实践。要求属性private提供公有的getter和setter方法。自考中常考命名规范getXxx(),setXxx(),isXxx()(用于布尔类型)。// 典型JavaBean示例 public class Student { private String name; // 私有属性 private boolean graduated; // 布尔属性 // 公有getter/setter public String getName() { return name; } public void setName(String name) { this.name name; } // 布尔属性getter可以是isXxx public boolean isGraduated() { return graduated; } public void setGraduated(boolean g) { this.graduated g; } }3.1.2 继承理解super与this的战场继承的难点在于构造方法的调用链和父子类成员的访问。构造方法链子类构造方法的第一行如果没有显式调用super(...)或this(...)编译器会自动加上super()。这意味着一定会先调用父类的无参构造方法。如果父类没有无参构造子类构造必须显式用super(参数)调用父类的有参构造。笔记会用流程图清晰展示这个调用过程。supervsthisthis指代当前对象用于访问本类的成员变量、方法或调用本类的其他构造方法(this(...))。super指代父类对象用于访问父类的成员尤其是被子类覆盖的或调用父类的构造方法(super(...))。3.1.3 多态编译看左运行看右这是最大的难点。笔记会用一个万能口诀来破解“编译期看引用类型左边运行期看实际对象类型右边”。成员变量不具备多态性。访问哪个完全由引用类型左边决定。成员方法具备多态性。普通方法看右边实际对象静态方法看左边引用类型。class Father { String str Father; void show() { System.out.println(Father.show); } static void staticShow() { System.out.println(Father.staticShow); } } class Son extends Father { String str Son; // 隐藏了父类的str Override void show() { System.out.println(Son.show); } // 重写 static void staticShow() { System.out.println(Son.staticShow); } // 隐藏 } public class Test { public static void main(String[] args) { Father obj new Son(); System.out.println(obj.str); // 输出Father (看左边) obj.show(); // 输出Son.show (看右边) obj.staticShow(); // 输出Father.staticShow (看左边静态方法) } }通过这样的对比表格和代码多态的规则就一目了然了。3.2 异常处理不仅仅是try-catch异常处理常被轻视但却是编写健壮程序的必备技能自考中常以阅读程序题或简答题形式出现。3.2.1 异常分类的清晰图谱笔记会绘制清晰的异常类继承树Throwable-Error(不可处理如OutOfMemoryError) /Exception-RuntimeException(运行时异常非受检) 和其他Exception(受检异常)。关键区别受检异常如IOException必须在编译时被处理try-catch或throws否则通不过编译。运行时异常如NullPointerException,ArrayIndexOutOfBoundsException不需要强制处理。3.2.2 try-catch-finally的执行顺序这是必考点。笔记会总结铁律执行try块。如果发生异常跳转到匹配的catch块。无论是否发生异常或是否被捕获finally块最终都会执行除非在try或catch中调用了System.exit(0)。return的执行时机try或catch中的return语句会先计算返回值并暂存然后去执行finally最后返回之前暂存的值。如果finally里也有return则会覆盖之前的返回值这是一种不好的实践笔记会重点警告。public static int test() { try { System.out.println(try); return 1; } catch (Exception e) { return 2; } finally { System.out.println(finally); // return 3; // 如果放开方法永远返回3覆盖了try中的1 } } // 输出try - finally - 返回13.3 数组与集合从固定长度到动态容器这是从基础语法向实用编程过渡的关键一章。3.3.1 数组的深入理解数组是引用类型。int[] arr new int[3];这行代码做了两件事在栈中创建引用变量arr在堆中开辟一块连续空间存放3个int初始值为0。笔记会强调数组的length属性是final的创建后不可变这是数组最大的限制。3.3.2 集合框架的对比学习为了克服数组的缺陷Java提供了集合框架。笔记不会罗列所有API而是用对比表格抓住核心特性ArrayListLinkedListHashSetHashMap底层动态数组双向链表哈希表哈希表链表/红黑树顺序插入顺序插入顺序无序不保证键无序LinkedHashMap有序重复允许允许不允许键不允许重复值允许查找性能O(1)(按索引)O(n)O(1)(平均)O(1)(平均)增删性能尾部O(1)中间O(n)O(1)(已知位置)O(1)O(1)线程安全否否否否自考重点常用遍历头尾操作去重键值对存储put/get选择策略需要频繁按索引访问用ArrayList需要频繁在头部插入删除用LinkedList需要快速去重用HashSet需要存储键值对用HashMap。遍历方式笔记会详细对比for循环、增强for循环、迭代器(Iterator)在每种集合上的用法和注意事项特别是如何在遍历时安全地删除元素必须使用迭代器的remove方法。4. 典型代码题分析与手写训练自考的编程题往往不是要求你写一个完整的系统而是考查你对特定语法点、算法逻辑的掌握。笔记会精选高频题型进行“庖丁解牛”式的分析。4.1 字符串操作String、StringBuilder、StringBuffer考题常围绕字符串翻转、查找、替换、分割展开。核心区别String不可变字符序列。任何修改都会产生新对象。适用于字符串常量、不频繁修改的场景。StringBuilder可变字符序列线程不安全但性能最高。适用于单线程下频繁修改字符串。StringBuffer可变字符序列线程安全方法有synchronized修饰性能稍低。适用于多线程下修改字符串。例题字符串翻转// 方法1使用StringBuilder最常用最高效 public static String reverse1(String str) { return new StringBuilder(str).reverse().toString(); } // 方法2转换为字符数组前后交换考查数组操作 public static String reverse2(String str) { char[] chars str.toCharArray(); int left 0, right chars.length - 1; while (left right) { char temp chars[left]; chars[left] chars[right]; chars[right] temp; left; right--; } return new String(chars); } // 方法3递归考查递归思想效率低仅作理解 public static String reverse3(String str) { if (str null || str.length() 1) return str; return reverse3(str.substring(1)) str.charAt(0); }笔记会分析每种方法的时间复杂度、空间复杂度并指出在自考答题时优先选择方法1因为它最简洁、意图最明确。4.2 文件I/O操作字节流与字符流的选用文件操作题通常要求读取文件内容进行处理后写入新文件。流的选择决策链操作对象是二进制文件如图片、视频还是文本文件二进制 -字节流(InputStream/OutputStream)文本 -字符流(Reader/Writer)更方便能处理编码。是否需要缓冲以提高效率需要 - 套上BufferedInputStream/BufferedReader。是否需要按行读取需要 - 使用BufferedReader的readLine()方法。标准模板代码// 模板使用缓冲字符流复制文本文件高频考点 import java.io.*; public class FileCopy { public static void main(String[] args) { // 声明在try外部方便finally关闭 BufferedReader br null; BufferedWriter bw null; try { br new BufferedReader(new FileReader(source.txt)); bw new BufferedWriter(new FileWriter(target.txt)); String line; while ((line br.readLine()) ! null) { // 逐行读取 bw.write(line); // 写入一行 bw.newLine(); // 写入换行符readLine()会去掉换行 } bw.flush(); // 刷新缓冲区确保数据写入文件 System.out.println(文件复制成功); } catch (IOException e) { e.printStackTrace(); } finally { // 关闭资源注意顺序和空指针判断 try { if (bw ! null) bw.close(); } catch (IOException e) { e.printStackTrace(); } try { if (br ! null) br.close(); } catch (IOException e) { e.printStackTrace(); } } } }实操心得在Java 7及以后强烈建议使用try-with-resources语句自动关闭资源代码更简洁安全。但自考大纲可能仍考查传统写法因此两种方式笔记都会详细说明并解释try-with-resources的原理。5. 备考策略与常见问题避坑指南5.1 高效复习时间线规划第一阶段通读教材与笔记约4周。以笔记为主线遇到不理解处回溯教材。目标是建立知识框架完成笔记中所有“概念精讲”和“代码实证”部分的理解不追求记忆。第二阶段真题驱动精准突破约3周。开始按章节刷近5-10年的真题。遇到错题立即回到笔记对应部分用红笔标注并在笔记空白处记录错题知识点和易混淆点。这个阶段的目标是暴露自己的知识盲区。第三阶段模拟与背诵约2周。进行整套试卷的计时模拟考试。同时集中背诵笔记中标注为“识记”的概念、定义、特点以及自己总结的错题本。第四阶段考前冲刺约1周。快速过一遍笔记的所有标题、加粗重点、自己标注的易错点。不再做新题只看错题。保持每天手写一段关键代码如单例模式、文件复制维持手感。5.2 考场实战技巧与答题规范选择题善用排除法。对于“下列说法错误的是”这类题先找出一个绝对正确的选项就能缩小范围。涉及代码片段的题可以在草稿纸上简单推演。填空题注意语法细节。比如定义数组时int[] arr和int arr[]都正确但填空题的空位可能只适应其中一种。方法名、变量名拼写要绝对准确。程序阅读题这是拿分关键。按执行顺序在代码旁注释每行的输出结果或变量值的变化。特别注意循环的边界条件、递归的出口。编程题即使不能完全写出也要尽力写出关键结构如类定义、方法签名、核心逻辑。写出正确的import语句、try-catch结构都能获得步骤分。保持代码缩进整洁命名规范。时间分配建议客观题选择、填空控制在30-40分钟内留足时间给主观题。编程题至少留出25分钟。5.3 常见疑难问题速查与解决Q和equals()的区别总是搞混A记住一个场景比较的是两个变量引用是否指向同一个内存对象地址。equals()比较的是两个对象的内容是否逻辑相等。对于String比较地址equals()比较字符序列。对于自定义类如果不重写equals()它默认行为和一样比较地址。笔记会提供重写equals()和hashCode()的标准模板。Q接口和抽象类到底什么时候用哪个A这是一个设计层面的问题。简单决策当你需要定义一个“契约”或“能力”并且不关心具体实现者是否有继承关系时用接口如Comparable可比较Runnable可运行。当你需要为一些相关类提供公共的代码实现和字段并且这些类有明确的“是一种is-a”关系时用抽象类如Animal作为Dog和Cat的抽象父类可以提供name属性和eat()方法的部分实现。接口强调“能做什么”抽象类强调“是什么”。Q运行程序时出现java.lang.OutOfMemoryError怎么办A这在自考编程题中不常见但理解它有助于深入理解JVM。这表示堆内存耗尽。根本原因通常是1) 创建了太多大对象且未释放如在一个无限循环中不断向集合添加数据2) 存在内存泄漏对象已不再使用但仍有引用指向它导致GC无法回收。解决方案不是盲目加大JVM内存-Xmx参数而是检查代码中是否存在集合对象只增不减、大量缓存未设置过期时间、或者静态集合长期持有对象引用等情况。对于自考学习重点是理解错误原因而非复杂调优。这份笔记的撰写过程也是我对自己Java基础知识的一次系统性重铸。最大的体会是学习编程尤其是应对考试“理解”远比“死记”重要而“动手”又是检验“理解”的唯一标准。不要满足于看懂笔记里的代码一定要在IDE里敲一遍改几个参数故意写错看看报什么错这样才能把知识真正内化。希望这份融合了考点、代码与经验的笔记能成为你自考路上的一把利器不仅助你顺利通关更能为你未来的编程生涯打下一个坚实的底子。如果在使用笔记的过程中有任何问题欢迎通过项目仓库的Issue功能与我交流我们一起让它变得更完善。