这里保存 Java 课程练习和学习说明。Java 源码必须遵守类名与文件名规则,因此不能直接照搬 C/Python 的 NN_日期_主题.java 命名方式;首次整理顺序和日期记录在配套文档中。系统的知识点、难点和掌握标准见 Java 学习指南。
| 目录 | 源码数 | 学习重点 |
|---|---|---|
| 01_基础语法 | 3 | 类、main、基本类型、类型转换、运算符、短路求值和三元表达式 |
| 02_分支与循环 | 10 | 输入校验、条件分支、switch、三种循环、嵌套循环、统计、极值和持续交互 |
| 03_方法与数组 | 10 | 方法定义与重载、值传递与数组引用、数组遍历、素数/约数/数字拆位/第二大值/数对统计、冒泡排序、线性查找和二分查找 |
| 04_综合项目 | 1 | 菜单循环、多方法分工、固定容量平行数组、输入校验、学号查找、统计和同步排序 |
| 05_面向对象 | 3 | 类、对象、构造方法、引用、封装、私有字段、getter/setter、this、static 和对象传参 |
当前只创建了有真实源码的目录。03_方法与数组 提供方法语义和入门算法,04_综合项目 组合菜单与数组,05_面向对象 第一次正式引入类对象、构造方法、引用别名、封装和静态成员。继承、多态、接口、集合、正式自动测试和工程构建仍没有足够资源,因此不提前建立空目录。
建议先按 1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12 → 13 → 14 打好基础,再按 15 → 16 → 17 → 18 → 19 → 20 → 21 → 22 → 23 学习方法语义和入门算法,完成 24 号综合项目后进入 25 → 26 的面向对象阶段。先运行程序,再阅读简介,卡住时再看零基础教程。Student、StudentTest 和 EncapsulationStaticDemo 也保留了大量原附件注释,编译器会忽略这些注释。
Java 与 C/Python 不同:如果一个类声明为 public class BasicTypes,源文件就必须叫 BasicTypes.java。因此当前采用以下规则:
- 源码文件名遵守 Java 自身的类名约束,优先使用清晰的
ClassName.java。 - 练习序号和首次进入仓库的日期写在配套文档名、导航表格和学习顺序中。
- 不为了套用 C/Python 编号格式去改
public class的文件名。 - 历史附件
hellojava.java保留原命名,避免未经授权修改源码;正式新写 Java 入门程序时优先使用HelloJava.java、BasicTypes.java这类大小写规范的类名。
hellojava.java 是有效的,因为它的类没有声明为 public;运行时使用的是类名 hellojava,不是文件名或另一个猜测的类名。
本机已使用 OpenJDK 21。先在仓库根目录创建一个临时输出目录,避免把 .class 文件留在仓库:
java_dir=$(mktemp -d /tmp/java-practice.XXXXXX)
javac -encoding UTF-8 -Xlint:all -d "$java_dir" "Java/01_基础语法/hellojava.java"
java -cp "$java_dir" hellojava运行基本类型练习:
java_dir=$(mktemp -d /tmp/java-practice.XXXXXX)
javac -encoding UTF-8 -Xlint:all -d "$java_dir" \
"Java/01_基础语法/BasicTypes.java"
java -cp "$java_dir" BasicTypes运行运算符练习:
java_dir=$(mktemp -d /tmp/java-practice.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/01_基础语法/OperatorsDemo.java"
java -cp "$java_dir" OperatorsDemo运行成绩等级程序:
java_dir=$(mktemp -d /tmp/java-practice.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/02_分支与循环/GradeLevel.java"
printf '90\n' | java -cp "$java_dir" GradeLevel运行不需要输入的循环基础程序:
java_dir=$(mktemp -d /tmp/java-loop.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/02_分支与循环/LoopBasics.java"
java -cp "$java_dir" LoopBasics运行带输入重试的星号三角形:
java_dir=$(mktemp -d /tmp/java-star.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/02_分支与循环/StarTriangle.java"
printf 'abc\n0\n3\n' | java -cp "$java_dir" StarTriangle运行方法与数组综合练习:
java_dir=$(mktemp -d /tmp/java-array.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/03_方法与数组/ArrayAndBubbleSort.java"
java -cp "$java_dir" ArrayAndBubbleSort程序不需要输入,内置 18 条教学检查。正常结果应只出现 [通过];若出现 [失败],即使命令退出码仍为 0 也必须继续排查,因为教学检查器没有主动改变退出状态。
运行方法基础和值传递练习:
java_dir=$(mktemp -d /tmp/java-method.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/03_方法与数组/MethodBasic.java" \
"Java/03_方法与数组/PassByValue.java"
java -cp "$java_dir" MethodBasic
java -cp "$java_dir" PassByValue带输入的算法练习各自使用 printf 送入测试数据,例如统计 1~100 中数字 0 的出现次数:
java_dir=$(mktemp -d /tmp/java-algorithm.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/03_方法与数组/DigitCount.java"
printf '100 0\n' | java -cp "$java_dir" DigitCount每份源码的完整命令和真实输出见同目录 15~23 号说明。SecondLargest.java 当前保留逻辑错误,编译能通过,但典型输入会输出 NO;不要把它当作正确标准答案。
运行成绩管理系统:
java_dir=$(mktemp -d /tmp/java-grade.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/04_综合项目/GradeManager.java"
printf '1\n1001\n张三\n88.5\n3\n4\n5\n0\n' |
java -cp "$java_dir" GradeManager程序支持最多 50 人、学号查重、整数/小数/成绩范围校验、并列最高分和同步降序排序。数据只保存在内存中,标准输入提前结束时通过 System.exit(0) 退出。
运行类、对象、构造方法和引用练习:
java_dir=$(mktemp -d /tmp/java-object.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/05_面向对象/Student.java" \
"Java/05_面向对象/StudentTest.java"
java -cp "$java_dir" StudentTest运行封装、this 与 static 练习:
java_dir=$(mktemp -d /tmp/java-encapsulation.XXXXXX)
javac -encoding UTF-8 -Xlint:all -Werror -d "$java_dir" \
"Java/05_面向对象/EncapsulationStaticDemo.java"
java -cp "$java_dir" EncapsulationStaticDemoStudentTest 必须和 Student 一起编译。EncapsulationStaticDemo.java 内部还有 SafeStudent 等包级类,只有 EncapsulationStaticDemo 是 public,因此运行类名仍是 EncapsulationStaticDemo。
SwitchBreakDemo.java 故意展示 11 处 [fallthrough],使用 -Xlint:all 编译会看到这些预期警告;如果加 -Werror,编译会按设计失败。不要为了通过严格检查而删除原始反例,详见同目录说明。
javac 编译源文件,java 启动指定类。-d 把编译结果放进临时目录,-cp 告诉 Java 去哪里查找编译后的类。完整环境说明见 开发环境与 Git 操作指南。
- 先能独立写出一个类和一个
main方法。 - 能解释
System.out.println为什么必须写在main的调用路径中。 - 能列出八种基本类型,以及
String为什么不属于基本类型。 - 能解释自动类型转换、强制类型转换和整数除法。
- 能手工说明为什么
2147483647 + 1在表达式中会溢出,以及为什么加L后结果不同。 - 能区分
&&与&、||与|,并说明短路为什么能保护除以零的表达式。 - 能沿着
case顺序追踪switch,说明break和default的作用。 - 能写出闰年条件和成绩边界,测试 1900、2000、59、60、89、90、100、非法输入。
- 能说明
while与do-while在首次条件为假时的执行次数差异。 - 能手工跟踪单层循环和外层、内层循环的变量变化。
- 能写出九九乘法表和带输入校验的星号三角形。
- 能在循环中维护累加器、计数器和当前最大值/最小值。
- 能说明随机猜数字程序的秘密数字、有效猜测次数和循环出口。
- 能解释数组默认值、下标、
length和普通for与增强for的差别。 - 能画出数组直接赋值、
Arrays.copyOf和数组传参的引用关系。 - 能手工跟踪冒泡排序、线性查找和二分查找,并说明二分查找的有序前提。
- 能说明 Java 只有值传递,数组方法修改的是共同引用指向的元素。
- 能根据参数个数和类型判断方法重载会选哪个版本。
- 能分别写出素数判断、正约数枚举、数字拆位统计和不同下标数对统计。
- 能定位“数组默认值未读入、最大值初始化、
found状态和输出分支”共同造成的逻辑错误。 - 能画出成绩管理系统中
ids、names、scores三个平行数组和count的关系。 - 能解释菜单程序从
main到业务方法再返回菜单的完整调用路径。 - 能在排序时同步交换三个数组,并设计空名单、重复学号、并列最高分和容量上限测试。
- 能解释类、对象、构造方法、实例字段和实例方法,并画出对象引用关系。
- 能说明封装为什么同时要求私有字段、受控 setter 和构造校验。
- 能区分实例字段与
static字段、实例方法与static方法。 - 能判断对象传参时“修改共同对象”和“重新赋值形参”的不同结果。
- 合上源码,自己写一个数组求和与冒泡排序程序,再写一个带退出条件的小游戏。
当前已经覆盖程序入口、基本类型、主要运算符、输入校验、条件分支、循环、方法拆分与重载、值传递、数组引用、多种入门算法、成绩管理项目,以及类对象、构造方法、封装、this、static 和对象引用传参。这个阶段提供面向对象入口,不代表已经掌握继承、多态、接口、集合或文件持久化。
新增 Java 练习时:
- 根据主要学习目标建立或选择二级目录。当前已有
01_基础语法、02_分支与循环、03_方法与数组、04_综合项目和05_面向对象;后续继承、多态等目录等真实练习出现后再新增。 - 源码文件名遵守
public类的文件名要求。 - 在源码旁增加带序号和日期的
_简介与学习建议.md;内容复杂时再增加_零基础教程.md。 - 编译时使用 UTF-8,并把
.class输出到临时目录。 - 未经明确授权,不修改原始学习代码;发现注释或代码问题时先在学习说明中记录。
- 如果是故意演示警告的源码,在说明中写清预期警告和严格编译结果,不用修改源码来掩盖教学现象。
- 如果源码能编译但逻辑错误,分别记录当前真实输出、题目预期、出错位置和最小修复思路;需要修正代码时另建版本,不覆盖原始附件。