
简介《Java基础入门》课后习题答案是一份面向Java初学者的课后练习对照资料适合正在学习Java语言基础、程序设计入门与面向对象编程的学生用于核对填空、判断、选择、简答及编程题的解答思路也可作为课堂复习和考前查漏补缺的参考答案。压缩包内共1个doc文档约214KB以Word文档形式整理便于在电脑或移动端直接阅读、批注与打印。内容按章节组织覆盖Java开发入门中的JDK与JRE关系、javac编译与path/classpath配置Java编程基础中的八种基本数据类型、运算符与短路逻辑、方法重载、循环求和及数组排序以及面向对象部分的封装、继承、多态、构造方法、this、权限修饰符和静态变量等每章题型较完整简答题侧重概念辨析编程题给出HelloWorld、奇数累加、冒泡排序和Student类封装等参考答案方便对照代码结构与实现细节。已有5694人学习适合需要系统刷题与自检的入门读者。1. 先弄清一件事这份课后习题答案不是拿来抄的很多人刚接触 Java 入门第一反应是找一份课后习题答案然后对着屏幕一行一行往下抄。抄完第一章感觉挺好第二天打开编辑器光标闪了半天连一个能跑起来的 HelloWorld 都敲不出来。这份 Java 基础入门的课后习题答案按教材章节一共排了九章前面是 Java 开发入门、编程基础、面向对象上下两篇后面是常用类、集合、IO、GUI 和 JDBC。每章的填空、判断、选择、简答和编程题都给了参考答案编程题还带完整可编译的代码。它真正好用的方式是当“校对工具”和“进度标尺”你自己先做一遍做完拿答案对对不上再回头看是哪一步想岔了。新手拿它当抄写本抄完就忘拿它当镜子照才知道自己哪块是空的。2. 第一步先让代码跑起来JDK、JRE 和你的第一个 HelloWorld学 Java 最容易劝退的瞬间不是语法看不懂是装完一堆东西之后连“我到底装成功了没有”都不知道。这一章就把第 1 章“Java 开发入门”的答案拆成能动手的步骤跟着做完你屏幕上会真的跳出第一行字。2.1 JDK 和 JRE 到底差在哪教材第 1 章填空题的答案里有 JRE简答题又专门问了 JRE 和 JDK 的区别这题几乎每套卷子都会出现。用一句大白话概括JRE 是“能看剧的电视”JDK 是“能拍剧的摄制组”。JRE 全称 Java 运行时环境里面装的是程序跑起来需要的基本条件和一批基础类库比如输入输出类、图形界面类、网络类。普通用户只需要运行别人做好的程序那装一个 JRE 就够了。JDK 全称 Java 开发工具包除了包含 JRE还带了编译工具、打包工具、文档制作工具这些开发用的东西。你要自己写代码就必须装 JDK。名字里面有什么谁需要新手要不要单独装JVM负责把字节码翻译成机器能执行的指令所有运行环境不用装 JDK 时自带JREJVM 一批基础类库只想运行程序的人不用JDK 里已经包含JDKJRE 编译器 javac 一堆开发工具写代码的人要装这一个就够这里有个新手最常见的重复劳动装完 JDK 后又去单独下载一个 JRE。没必要JDK 里面已经打包好了多装一份反而容易出现版本对不上的怪问题。我第一次折腾的时候就干过这事两个版本混在一起命令行敲出来 的版本号和我以为的完全不是一回事查了半天才反应过来。2.2 装完之后用三行命令确认环境装完先别急着写代码打开命令行敲下面三行。能正常返回版本信息说明环境基本没问题。# 查看运行时环境版本走的是 JRE 那条路 java -version # 查看编译器版本走的是 JDK 那条路 javac -version # 查看 path 环境变量里有没有配好 Java 的 bin 目录 echo $PATH # macOS / Linux 用这条 echo %PATH% # Windows 用这条三条命令的含义不一样别混。java -version能出版本、javac -version报“不是内部或外部命令”说明你的 JRE 装上了但编译器没进到系统路径里问题出在环境变量不在安装包。反过来javac能用而java不行那多半是 path 里混进了旧版本。环境变量这块教材第 1 章填空题答案是“path、classpath”。path 的作用是让系统在任何目录下都能找到 java 和 javac 这两个命令所以你只需要把 JDK 安装目录下的 bin 文件夹路径加进去。classpath 是告诉 Java“去哪里找你要用的类文件”新手阶段基本不用手动配默认当前目录就够用配错了反而会引发一堆“找不到符号”的报错。提示改完环境变量一定要重开一个命令行窗口旧窗口读的还是改之前的那份配置改完不生效八成是这个原因。2.3 第一个例子HelloWorld 逐行拆开看新建一个文本文档把下面这段敲进去存成HelloWorld.java注意大小写一个都不能错。// 文件名必须叫 HelloWorld.java和 public class 后面的名字完全一致 public class HelloWorld { // main 方法是程序入口JVM 从这里开始执行 public static void main(String[] args) { // 向控制台打印一行文字println 表示打印完换行 System.out.println(这是第一个 Java 程序!); } }逐行拆一下。public class HelloWorld定义了一个叫 HelloWorld 的类public 表示这个类对外公开而 Java 规定一个文件里最多只能有一个 public 类并且文件名必须和它同名。public static void main(String[] args)是固定写法四个部分各管一件事public 让 JVM 能调用它static 表示不用创建对象就能调用void 表示不返回任何值String[] args 是接收命令行参数的字符串数组。System.out.println(...)是调用系统输出流打印内容并换行引号里的东西原样输出。写完保存在这个文件所在的目录下打开命令行依次执行# 第一步编译把 .java 源文件翻译成 .class 字节码文件 javac HelloWorld.java # 第二步运行注意这里写的是类名不带 .class 后缀 java HelloWorld第一行命令如果没报错目录下会多出一个HelloWorld.class文件。第二行命令会输出“这是第一个 Java 程序!”。这两步正好对应教材第 1 章简答题里那道“Java 程序运行时必须经过哪两个步骤”先编译成字节码再由 Java 虚拟机解释执行。这里有个细节新手特别容易翻车javac后面跟的是文件名要带.javajava后面跟的是类名不能带.class。写成java HelloWorld.class就会报“找不到或无法加载主类”这个坑我在第 4 章还会再说一遍。3. 语法打底八种基本类型、短路运算和那段看不懂的冒泡排序第 1 章过了之后第 2 章“Java 编程基础”的题目量会明显变大。填空题、判断题、选择题都还好说真正卡人的是简答题和编程题。这一章挑出四个最典型的知识点把答案背后的“为什么”讲清楚。3.1 八种基本数据类型一张表加一句口诀教材简答题第 1 题问的就是这八种类型答案里连占几个字节都列出来了。记的时候别硬背先分四组整数四个、小数两个、字符一个、布尔一个。类型类别占用字节大概范围或取值byte整数1-128 到 127short整数2-32768 到 32767int整数4约正负 21 亿long整数8很大赋值时要加 Lfloat小数4精度低赋值时要加 fdouble小数8精度高小数默认就是它char字符2单个字符用单引号boolean布尔1只有 true 和 false新手最容易在 long 和 float 上翻车。写long a 10000000000;会编译不过因为整数默认按 int 处理超范围了就得写成10000000000L。同理float b 3.14;也过不了小数默认是 double得写3.14f。这不是玄学就是编译器在按默认规则给你判类型。char 占两个字节这点也常被问。原因是 Java 里的 char 用的是 Unicode 编码不是早期的 ASCII一个字符要用两个字节才装得下。你写char c A;没问题写char c A;就报错双引号是字符串单引号才是字符这个引号错误在选择题里几乎是必考项。3.2 和 的区别一行代码就能看出差别教材这道简答题的答案是两边都会执行左边为 false 时右边直接不执行。听着抽象跑一段代码立刻明白。public class ShortCircuit { public static void main(String[] args) { int x 2; int y 0; // 用 连接(x y) 为 true右边必须执行于是 x / y 触发除零 boolean b1 (x y) (x / y 0); // 用 连接(x y) 为 true右边同样要执行 // 把条件改成 (x y) 再试一次右边就完全不会被执行 boolean b2 (x y) (x / y 0); System.out.println(b2); } }把第一行的换成并保持x y程序照样抛异常因为左边为 true 时右边必须算。真正体现“短路”的是第二行x y是 false直接判定整个表达式为 false右边那个会除零的式子根本不会被执行程序安安稳稳输出 false。这个知识点在实际开发里不是考试专用。后端代码里写if (user ! null user.getName() ! null)这种判断靠的就是短路特性前面挡一道、后面才安全。要是把误写成空指针异常立刻找上门。顺带一提|和||也是同样的道理||左边为 true 时右边不执行。3.3 冒泡排序把双层循环拆成三轮看第 2 章编程题第 2 题是数组排序答案给的是冒泡排序。这段代码新手看十遍还是懵因为它有两层循环加一个临时变量交换四件事挤在一起。先看代码。public class ArraySort { public static void main(String[] args) { int[] arr {25, 24, 12, 76, 101, 96, 28}; // 外层循环控制比较的轮数n 个元素最多比 n-1 轮 for (int i 0; i arr.length - 1; i) { // 内层循环负责每轮相邻两个元素的比较 // 减 i 是因为每轮结束末尾就多了一个已经排好的元素 for (int j 0; j arr.length - i - 1; j) { // 前面比后面大就交换这样每轮最大的会冒到末尾 if (arr[j] arr[j 1]) { int temp arr[j]; arr[j] arr[j 1]; arr[j 1] temp; } } } // 遍历打印排序结果 for (int i 0; i arr.length; i) { System.out.print(arr[i] ); } } }先单独看交换那三行这是所有排序的基础动作。想把两个杯子里的水对调得先拿一个空杯子。temp就是那个空杯子先把 arr[j] 倒进 temp再把 arr[j1] 倒进 arr[j]最后把 temp 里的倒回 arr[j1]。顺序错一步两个位置就会变成一样的值这是新手写交换时最高频的翻车点。再看循环。第一轮 i0内层从 j0 跑到 j5把 25 和 24 比、24 和 12 比一路比下去最大的 101 会被一路换到最后一个位置。第二轮 i1内层少跑一次因为末尾的 101 已经归位不用再管它。这就是arr.length - i - 1里那个- i的来历每轮结束有序区就多一个元素无序区就少一个。想验证自己真看懂了把数组换成{5, 4, 3, 2, 1}在纸上把每一轮结束后的数组抄一遍。五轮之后你会看到它变成1 2 3 4 5这个过程走通一次比看十遍代码管用。3.4 方法重载同名方法凭什么不打架第 2 章简答题第 3 题问的是方法重载答案是“同一个类中可以声明多个同名方法参数个数或类型不同”。很多人到这里会疑惑名字都一样程序怎么知道该调哪个public class OverloadDemo { // 两个 int 相加 public static int add(int a, int b) { return a b; } // 三个 int 相加参数个数不同 public static int add(int a, int b, int c) { return a b c; } // 两个 double 相加参数类型不同 public static double add(double a, double b) { return a b; } public static void main(String[] args) { System.out.println(add(1, 2)); // 输出 3匹配第一个 System.out.println(add(1, 2, 3)); // 输出 6匹配第二个 System.out.println(add(1.5, 2.5)); // 输出 4.0匹配第三个 } }编译器在编译阶段就会根据你传进去的实参个数和类型决定绑定到哪一个方法这个动作叫静态绑定。所以三个同名方法在内存里其实是三个不同的方法各有各的参数列表不冲突。要小心的是只有返回值类型不同不算重载。写两个方法名字和参数完全一样只有一个返回 int、一个返回 double编译器会直接报错因为它判断不了你想要的到底是哪个。判断标准只有一条参数列表是否不同跟返回值没关系。4. 避坑与排查新手卡在这五个地方最多答案看得懂、代码也敲了但还是跑不起来这是入门阶段最磨人的状态。下面五条是新手最常撞上的每条按“看到什么现象、为什么、怎么解决”写遇到了直接对号入座。4.1 类名和文件名不一致编译直接报错现象命令行执行javac HelloWorld.java返回“类 HelloWorld 是公共的应在名为 HelloWorld.java 的文件中声明”。原因Java 规定一个源文件里如果出现 public 类文件名必须和这个类名完全相同大小写也算。你文件存成了helloworld.java或者Hello.java编译器就不认。解决把文件名改成和 public 类名一模一样。这里有个血泪经验Windows 默认隐藏文件扩展名你以为存的是HelloWorld.java实际可能变成了HelloWorld.java.txt。打开资源管理器的“显示文件扩展名”选项确认一下能省掉半小时的自我怀疑。4.2 javac 过了java 说找不到主类现象编译成功目录里也有.class文件执行java HelloWorld却报“找不到或无法加载主类”。原因三种可能。一是写成了java HelloWorld.class类名不能带后缀二是当前命令行的工作目录不是 class 文件所在目录三是源文件里写了package语句类被放进了包路径里运行时必须加上完整包名。解决先用dir或ls确认当前目录下确实有那个 class 文件再确认命令里只写类名。如果代码开头有package com.demo;那就得在包的上一级目录执行java com.demo.HelloWorld路径层级一个都不能少。初学者阶段建议先别加包名等第一个程序跑通了再折腾。4.3 字符串比较用了 结果时对时错现象两个内容一样的字符串用比较有时返回 true有时返回 false换台机器结果又变了。原因比较的是引用地址也就是两个变量是不是指向内存里的同一个对象。字符串常量放在常量池里内容相同的字面量可能指向同一块内存所以偶尔返回 true但用new String(...)或者在运行时拼出来的字符串地址一定不同。解决比较内容一律用equals。写str1.equals(str2)稳妥。如果怕 str1 是 null 引发空指针把确定不为 null 的放前面或者用Objects.equals(str1, str2)。这个坑在集合那章还会再遇到一次性质和这里完全一样。4.4 数组越界冒泡排序里最容易写错的一个下标现象程序运行到一半抛出ArrayIndexOutOfBoundsException后面跟着一串数字。原因九成是把j arr.length - i - 1写成了j arr.length - i或者干脆写成j arr.length - 1。内层循环多跑一次arr[j 1]就越过了数组的最后一个位置。解决看到这个异常先去看异常信息里括号中的数字那就是越界的下标。数组长度为 7合法下标是 0 到 6报出 7 就说明多走了一步。养成习惯只要循环条件里出现arr[j 1]这种写法就回头检查边界是不是多减了一个 1。4.5 IO 流用完不关文件内容缺一截现象第 7 章 IO 的编程题照着答案敲完程序不报错但打开目标文件发现内容是空的或者只写进去一半有时候还会提示文件被占用、删不掉。原因输出流有缓冲区数据先写进内存攒够了才真正落到磁盘。程序结束时没有调用close()缓冲区里剩下的数据就丢了。文件被占用则是因为流对象还持有文件句柄。解决写完一定要close()而且最好放在 finally 里保证出异常也能关掉。更现代一点的写法是用 try-with-resources把流的创建写在 try 后面的括号里出了这个代码块会自动关闭不用手写 close。教材答案里给的是传统写法你照着敲没问题但要知道还有更省心的方式。5. 从面向对象到集合把答案当练习册刷的三条线第 3 章往后题目的难度不在语法而在“想问题的角度”变了。前面是让程序按步骤走从这里开始要让程序按对象组织。这一章把面向对象上下两篇、常用类和集合这四章的答案串成三条线一条一条过。5.1 封装、继承、多态三个类讲完教材第 3 章简答题说得很清楚封装是把属性和行为包起来不让外界知道实现细节继承是在不改原类的前提下扩展功能多态是用父类类型的变量引用子类对象同一个方法调用呈现出不同行为。// 父类把属性私有化只留方法对外这就是封装 class Student { private String name; private int age; public Student(String name, int age) { this.name name; this.age age; } public String getName() { return name; } public void show() { System.out.println(name: name age: age); } } // 子类extends 继承父类super 调用父类构造方法 class UnderGraduate extends Student { private String degree; public UnderGraduate(String name, int age, String degree) { super(name, age); // 必须放在第一行 this.degree degree; } // 重写父类的 show 方法方法名、参数、返回值都相同 Override public void show() { System.out.println(name: getName() degree: degree); } } public class Test01 { public static void main(String[] args) { // 父类引用指向子类对象这就是多态 Student s1 new Student(zhangsan, 16); Student s2 new UnderGraduate(lisi, 20, 本科); s1.show(); // 调用父类版本 s2.show(); // 调用子类重写后的版本 } }这段代码里最值得盯的是最后两行。两个变量的类型都是 Student但 s2 实际指向的是 UnderGraduate 对象运行时调用的是子类重写后的 show。编译时看左边类型运行时看右边对象记住这句话多态就懂了大半。super(name, age)那行也有讲究。子类构造方法执行前一定要先构造父类那部分所以 super 必须放在第一行写晚了编译器直接报错。另外注意 age 是父类的 private 属性子类访问不到代码里用getName()拿名字就是为了绕开私有访问限制这正好也体现了封装的意义。5.2 String 和 StringBuffer为什么反转字符串要用后者教材第 5 章简答题第 1 题问的就是这两者的区别String 是不可变类值一旦初始化就改不了StringBuffer 是可变字符串可以反复追加修改。编程题第 1 题要求把 “HelloWorld” 倒过来输出同时大小写互换。这个题如果用 String 硬拼每次拼接都会产生一个新对象循环十次就有十个废弃对象用 StringBuffer 则是在同一个缓冲区上不断追加。public class ReverseCase { public static void main(String[] args) { String str HelloWorld; // 转成字符数组方便按下标倒着取 char[] ch str.toCharArray(); StringBuffer buffer new StringBuffer(); // 从最后一个字符开始往前遍历 for (int i ch.length - 1; i 0; i--) { if (ch[i] A ch[i] Z) { // 大写转小写 buffer.append(Character.toLowerCase(ch[i])); } else if (ch[i] a ch[i] z) { // 小写转大写 buffer.append(Character.toUpperCase(ch[i])); } } System.out.println(buffer.toString()); // 输出 DLROwOLLEh } }结果是把原来的字符串倒过来同时每个字母的大小写翻转原来的小写 w 变成大写 W原来的大写 H 变成小写 h。ch[i] A ch[i] Z这种写法是在比较字符的编码值因为字符在底层就是数字所以能直接比大小。补充一句后来的 Java 版本里还有一个 StringBuilder用法和 StringBuffer 几乎一样区别是它不带同步锁单线程下更快。教材里讲的是 StringBuffer作业照它写就行等工作里写后端代码时你会经常看到 StringBuilder知道它们是同一类东西就够了。5.3 List、Set、Map 怎么选一张表定下来第 6 章集合是整本书里概念最密集的一章但落到实用层面其实就三个问题要不要重复、要不要顺序、是不是键值对。接口特点常用实现类典型场景List有序、可重复ArrayList、LinkedList按顺序存一批数据要按下标取Set无序、不可重复HashSet、TreeSet去重判断某个元素在不在Map键值对键唯一HashMap、TreeMap按名字查数据比如姓名对应年龄新手用 ArrayList 的时候常犯一个错以为remove(1)是删掉值为 1 的元素实际上删的是下标为 1 的那个。要删值得传包装类型或者用remove(Integer.valueOf(1))。这种“看着像但其实不是”的细节只有自己跑一遍才会记住。HashSet 的去重原理在编程题第 1 题里体现得最清楚。往 HashSet 里放三个 Person两个都叫 Jack只靠对象本身是去不掉的必须重写 hashCode 和 equals。class Person { String name; int age; public Person(String name, int age) { this.name name; this.age age; } // 名字相同就认为 hashCode 相同 Override public int hashCode() { return name.hashCode(); } // 名字相同就判定为同一个对象 Override public boolean equals(Object obj) { if (this obj) return true; if (obj null || !(obj instanceof Person)) return false; Person p (Person) obj; return p.name.equals(this.name); } }两个方法必须成对重写只写一个等于没写。HashSet 判断元素是否重复时先比 hashCode 定位到哪个桶再用 equals 逐个比。hashCode 一样但 equals 为 false会挂在同一个桶下面变成链表hashCode 不一样equals 压根不会被调用。这个机制初学不用深挖但“成对重写”这条必须刻进肌肉记忆。5.4 抽象类和接口一道形状面积题说清第 4 章简答题第 3 题问抽象类和接口的区别答案是抽象类用 abstract 修饰、不能被实例化通常要写子类继承接口是特殊的抽象类用 interface 定义里面只能放常量、抽象方法、静态方法和默认方法。编程题第 2 题给的形状面积例子最能说明接口的用处。// 接口只规定“必须有求面积这个能力”不管怎么算 interface Shape { double area(); } class Square implements Shape { private double side; Square(double side) { this.side side; } public double area() { return side * side; } } class Circle implements Shape { private double r; Circle(double r) { this.r r; } public double area() { return Math.PI * r * r; } } public class Test02 { public static void main(String[] args) { Shape square new Square(2); Shape circle new Circle(3); System.out.println(square.area()); // 4.0 System.out.println(circle.area()); // 约 28.27 } }正方形和圆形的计算方法完全不同但对外都只暴露一个 area() 方法调用方不需要知道里面怎么算。这就是接口的价值定标准不定实现。选哪个也有简单判据。如果几个类之间本来就是“是不是”的关系比如本科生是学生用继承抽象类如果是“有没有某种能力”的关系比如正方形有求面积的能力用接口。一个类只能继承一个父类但可以实现多个接口这也决定了接口更适合做能力的组合。6. 下一步学什么从做完习题到能写点东西九章答案刷完语法层面的东西你基本都见过一遍了但离“能写一个小东西”还有一段距离。这个距离不是靠再刷一遍题填上的得靠换一种练法。先看一个学习顺序建议按这个顺序往下走每一步都能自己验证结果不会陷进“学了不知道有什么用”的状态。阶段重点内容怎么算过关大概投入第一段把第 1 到 4 章的选择题和判断题全部重做一遍闭卷正确率到 90% 以上一周第二段第 7 章 IO 流手写文件拷贝、按行读文本能自己写出不丢数据的拷贝程序一周第三段多线程基础两个线程交替打印数字能说清为什么加了 synchronized 结果才稳定一周第四段第 9 章 JDBC连一个本地数据库做增删改查能跑通一次完整的查询并打印结果一到两周第五段用集合加 JDBC 写一个控制台版的小管理系统增删改查四个功能都能用两到三周第一段的目的是把地基夯死。很多人急着往后学结果 ArrayList 和数组的区别都说不利索后面写代码全靠猜。选择题和判断题看着简单但它们覆盖的是最容易记混的那些点闭卷能做对说明基础真的进去了。第二段开始就得动手了。IO 这块光看答案没用因为你永远不知道自己写的 close 有没有漏、缓冲区会不会丢数据。写完拷贝程序拿一个几兆的文件试对比源文件和目标文件的大小一致才算过。这个验证动作看着笨但能拦住绝大多数“我以为它对了”的错觉。第三段的多线程是很多人卡住的地方。别一上来就啃并发包先把两个线程交替打印 1 到 100 这个例子跑通观察不加锁时输出是怎么乱的再加 synchronized 看它怎么变整齐。亲眼见过乱序你才会真正理解锁在解决什么问题。第四段 JDBC 是整个入门阶段最有成就感的一步因为它第一次让程序和外部世界连上了。教材编程题里给了完整的六步流程加载驱动、获取连接、创建 Statement、执行 SQL、处理结果集、关闭连接。照着跑通一次查询把结果打印出来你会突然觉得前面那些语法都有了落点。第五段是把所有东西捏在一起。找一个自己感兴趣的题目比如一个记录读书清单的控制台程序用 List 存数据、用 JDBC 存到数据库、用 IO 做导出。这个程序不需要好看能跑起来、能增能删能改能查就够。写完这一个你就从“学过 Java”变成了“用过 Java”。还有一个容易被忽略的习惯每写完一段代码别急着往下写先问自己“我怎么知道它是对的”。是靠打印输出看结果还是靠对比文件大小还是靠故意传一个错误参数看它报不报错。这个自检动作我入门时完全没概念代码跑完不报错就默认正确结果交作业前一天才发现数据一直是错的回头查了三个小时。从那以后我每次写完关键逻辑都强制走一遍验证哪怕是打印一行中间结果也比盲目相信强。Java 作为一门开发语言生态确实厚后端项目里那些 Apache 开源组件你迟早会碰到但那是后面的事。眼下这一步把九章的答案当成练习册一题一题过跑通每一个编程题你会发现自己已经能看懂很多开源代码的骨架了。希望帮到你。本文还有配套的精品资源点击获取