Java基础题库实战:22道题+12道异常处理,避开编译与运行期的坑 简介这份资源面向Java初学者与求职备考人群系统整理了Java基础知识笔试题及参考答案可用于日常自测、课堂练习与面试前查漏补缺。内容覆盖基本概念、八种基本数据类型、运算符、顺序选择循环三类控制结构、函数、数组、集合框架、泛型与封装等核心知识点题目以选择题、程序输出判断和编程题为主并附有参考代码与解析便于对照理解易错点。资源包共1个docx文件约25KB体积轻便适合直接打印或导入笔记软件反复练习。目前已有1307人学习下载具备一定的参考价值。通过逐题演练读者可巩固Java语法细节熟悉String、Calendar、LinkedList等常用类的用法并借助编程题体会封装、泛型与集合在实际代码中的组织方式从而提升程序设计与开发能力。1. 一份能直接跑起来的 Java 基础题库到底值不值得存面试前一周翻出一份“Java 基础知识笔试题及答案”很多人第一反应是扫两眼答案就关掉。但真正带过人的工程师都清楚这类资源的价值不在答案本身而在题目背后那套被反复考、反复错的语法边界。这份资源把 Java 基础拆成 22 道选择/编程题加 12 道异常处理题覆盖包装类、equals 与 、Calendar 实例化、集合能否存重复元素、泛型方法、自定义异常、字符串与日期转换等高频点每道编程题都附了可编译的参考代码。它适合三类人准备笔试的应届生、想系统补语法漏洞的转岗开发者、以及需要给新人出练习题的带教者。下面按“先看清结构、再逐块跑通、最后避开编译与运行期的坑”这条线拆开讲重点放在那些答案对但代码一跑就翻车的地方。2. 把题库拆成可执行单元从包装类到集合的验证路径拿到一份题库最忌讳从头到尾当阅读理解做。我的习惯是先按知识点分块每块挑一道题写成可运行的最小 demo让编译器替我判断对错。这份资源的题目天然分成四块包装类与字符串第 1、2、7、11、16、17 题、日期与集合第 3、4、5、6、12、14、15 题、泛型与自定义结构第 9、10、13、19、20、21、22 题、异常处理异常部分第 3 到 12 题。分块之后你会发现很多选择题的“正确答案”其实依赖一个隐含前提比如第 6 题问list.add(2,B)的结果答案给的是运行时异常原因不是语法错而是LinkedList此时只有一个元素索引 2 越界。2.1 包装类与字符串先分清 valueOf、parseInt、toString 的返回类型第 7 题是典型的“看着简单、写起来容易混”的题。String.valueOf(10D)输出10.0String.valueOf(32)输出trueString.valueOf(data,1,3)从字符数组下标 1 开始取 3 个字符输出bcd。这三个调用同名不同参返回的都是String但入参类型决定了走哪个重载。第 16、17 题则反过来把字符串转成数值、把数值转成字符串方向一错结果就全错。我一般会写一个对照脚本把几个易混方法放在一起跑public class WrapDemo { public static void main(String[] args) { // valueOf 返回包装类或 StringparseInt 返回基本类型 int String s1 String.valueOf(10D); // double - 10.0 int i1 Integer.parseInt(200, 16); // 十六进制字符串 - 512 float f1 Float.parseFloat(123456); // 字符串 - 123456.0 String hex Integer.toHexString(365); // 十进制 - 16d System.out.println(s1 | i1 | f1 | hex); } }这段代码的关键在参数含义parseInt(200,16)的第二个参数是基数不是要转换的数很多人第一次会把200当成十进制再转十六进制方向搞反。toHexString返回小写若题目要求大写需自己toUpperCase()。第 17 题参考代码里手写了一个DtoX转换函数逻辑没错但绕实际开发中直接用Integer.toHexString更稳手写版适合用来理解进制转换的取余过程不建议放进生产代码。2.2 集合与日期Set 不重复、Map 的 value 可以是 List但别踩索引越界第 4 题问哪个集合不能存重复元素答案给的是Map这个答案需要打个问号。严格说Set才是不允许重复元素的集合Map的 key 不允许重复、value 可以重复。题目把Map列为答案大概率是想表达“Map 的 key 不可重复”但表述不严谨。做这类题时我建议以 JDK 文档为准Set实现类HashSet、TreeSet靠equals判重Map靠 key 的hashCode与equals。第 5 题问 Map 和 List 的关系正确答案是“Map 的 value 可以是 List 或 Map”这在实际业务里很常见比如一个分组结果用MapString, ListOrder存。第 6 题是这份题库里最值得动手跑的一道。代码先add(A)再add(2,B)此时链表长度为 1合法索引只有 0传 2 必然抛IndexOutOfBoundsException。答案写“运行时引发异常”是对的但很多人会误以为是编译错误。验证方式很简单import java.util.LinkedList; public class ListBoundDemo { public static void main(String[] args) { LinkedList list new LinkedList(); list.add(A); try { list.add(2, B); // 长度 1索引 2 越界 } catch (IndexOutOfBoundsException e) { System.out.println(捕获到 e.getClass().getSimpleName()); } } }参数说明add(int index, E element)的 index 必须满足0 index size()注意是小于等于 size等于 size 时是追加到末尾超过才越界。第 12、14 题的日期计算也有类似边界Calendar.MONTH从 0 开始输出时要1第 14 题用毫秒差除以24*60*60*1000算天数遇到跨夏令时或含时分秒的日期会丢精度稳妥做法是把两个Calendar的时、分、秒、毫秒清零后再相减。2.3 泛型与自定义 Stack类型擦除决定了你不能 new T[]第 19、20 题是泛型方法的代表。第 19 题用T extends Comparable约束类型必须可比较minmax里靠compareTo找极值第 20 题fromArrayToCollection(T[] a, CollectionT c)演示了数组到集合的搬运。这两题的共同坑是类型擦除运行时T被擦成Object或它的上界所以方法体里不能写new T[]也不能对T做instanceof判断。第 13 题用LinkedList手写StackaddFirst入栈、getFirst取栈顶、removeFirst出栈逻辑正确但要注意getFirst在空栈时抛NoSuchElementException生产环境应改用peekFirst返回 null 或先判空。import java.util.LinkedList; class StackT { private LinkedListT list new LinkedList(); public void add(T obj) { list.addFirst(obj); } // 入栈O(1) public T get() { return list.peekFirst(); } // 取栈顶空栈返回 null public T delete() { return list.pollFirst(); } // 出栈空栈返回 null } public class StackDemo { public static void main(String[] args) { StackString s new Stack(); s.add(1); s.add(2); s.add(3); System.out.println(s.get()); // 3 s.delete(); System.out.println(s.get()); // 2 } }这里把原题的Object换成了泛型T好处是取出时不用强转编译期就能发现类型错误。参数上peekFirst与getFirst的区别值得记牢前者空集合返回 null后者抛异常选哪个取决于你的调用方是否已经保证非空。3. 异常处理题的正确打开方式finally 的返回值会覆盖 try异常部分最容易翻车的是第 8、9 题。第 8 题try里returnfinally照样执行所以输出tryfinallycatch不参与。第 9 题更阴try里return 5/0抛异常catch返回2*36但finally里return 3会直接覆盖前面的返回值最终返回 3。这个行为在《Java 语言规范》里有明确定义但实际写业务代码时几乎没人会这么写考试考的就是你知不知道finally的优先级。3.1 多重 catch 的顺序子类在前父类在后第 6 题问多重 catch 里哪个异常类应最后列出答案是Exception。原因很直接catch 从上到下匹配如果把Exception放前面后面所有具体异常都不可达编译器直接报错。正确顺序是ArithmeticException、NumberFormatException、ArrayIndexOutOfBoundsException这类子类在前Exception兜底在后。第 7 题new String(null)抛NullPointerException因为String没有接受null的构造器重载能匹配到具体类型编译器选了String(String)然后传 null 进去。这类题光看答案记不住建议自己写一遍让 IDE 标红。3.2 自定义异常与输入校验别让异常吞掉真实错误第 11 题要求输入abc时抛自定义异常参考代码继承Exception并重写toString。这里有个常见误用自定义异常继承Exception属于受检异常调用方必须try-catch或声明throws如果继承RuntimeException则不受检适合参数校验类场景。第 12 题要求输入含非数字时程序仍能正常运行思路是用Scanner读字符串再parseInt捕获NumberFormatException后提示重输。我一般会把重试逻辑包成循环避免一次输错就退出import java.util.Scanner; public class SafeSubtract { public static void main(String[] args) { Scanner in new Scanner(System.in); while (true) { try { System.out.print(输入两个整数); int a Integer.parseInt(in.next()); int b Integer.parseInt(in.next()); System.out.println(差 (a - b)); break; } catch (NumberFormatException e) { System.out.println(含非数字请重新输入); } } } }参数说明in.next()按空白切分读取比nextLine()更适合“一行多个数”的场景parseInt遇到12.5也会抛NumberFormatException因为它是整数解析小数要用Double.parseDouble。捕获后不打印堆栈而给友好提示是业务代码和练习题的分水岭。4. 避坑与排查这五处答案对、代码却跑不通4.1 现象第 6 题照抄能编译一运行就崩原因LinkedList初始为空add(A)后 size 为 1add(2,B)的索引 2 超过 size抛IndexOutOfBoundsException。解决插入前用list.size()判断或改用add(B)追加理解add(index, e)的合法区间是[0, size]。4.2 现象第 12 题输出月份总差一个月原因Calendar.MONTH从 0 开始计数1 月返回 0。解决输出时get(Calendar.MONTH)1更彻底的做法是换java.time.LocalDategetMonthValue()直接返回 1 到 12避免这类偏移。4.3 现象第 14 题算出的天数偶尔差一天原因两个Calendar若带有时分秒毫秒差除以一天的毫秒数会截断跨夏令时地区还会少或多一小时。解决相减前把时、分、秒、毫秒全部set为 0或直接用ChronoUnit.DAYS.between(date1, date2)。4.4 现象第 19 题泛型方法传入int[]编译失败原因泛型不支持基本类型数组int[]不能赋给T[]因为T会被擦除为引用类型。解决改用包装类型Integer[]或在方法内部用Arrays.stream转成ListInteger再处理。4.5 现象第 9 题以为返回 6实际返回 3原因finally块中的return会覆盖try或catch中的返回值且finally一定执行。解决业务代码里避免在finally写return它还会吞掉异常finally只做资源释放返回值交给try或catch。5. 把题库变成自己的验证脚本一个可复用的自测习惯刷完这份题库如果只是对答案过两周基本忘光。我的做法是把每道编程题改成一个带断言的自测方法用main一次性跑完输出“通过/失败”这样每次改 JDK 版本或换 IDE 都能快速回归。下面是一个骨架把第 7、11、15 题的核心断言塞进去import java.util.*; public class SelfCheck { static int pass 0, fail 0; static void check(String name, Object actual, Object expected) { if (Objects.equals(actual, expected)) { pass; } else { fail; System.out.println(FAIL name 期望 expected 实际 actual); } } public static void main(String[] args) { // 第 7 题valueOf 系列 check(valueOfDouble, String.valueOf(10D), 10.0); check(valueOfBool, String.valueOf(3 2), true); check(valueOfChars, String.valueOf(new char[]{a,b,c,d}, 1, 3), bcd); // 第 11 题字符串比较与替换 String str1 It is; check(equals, str1.equals(It is), true); check(replace, str1.concat( a book.).replace(i, m), It ms a book.); // 第 15 题HashMap 覆盖同 key MapString, Integer map new HashMap(); map.put(张三, 90); map.put(李四, 83); map.put(李四, 100); check(mapSize, map.size(), 2); check(mapValue, map.get(李四), 100); System.out.println(通过 pass 失败 fail); } }这段脚本的价值在于把“看答案”变成“跑断言”。参数上Objects.equals能安全处理 null比直接或equals更省心String.valueOf(char[], int, int)的第二个参数是起始下标、第三个是长度不是结束下标这一点和第 7 题答案里的bcd对得上。跑通之后我会把失败项对应的题号记下来回头只看那几道比通读整份题库效率高得多。还有一个容易被忽略的点这份题库的参考代码大量使用原始类型raw type比如LinkedList list new LinkedList()、HashMap map new HashMap()。在 JDK 5 之后这样写会触发 unchecked 警告JDK 9 起部分场景还会报错。自己复现时建议全部补上泛型参数既消除警告也能提前暴露第 19 题那类类型不匹配的问题。从那以后我每次拿到一份题库类资源都强制先把它改写成带断言的自测脚本再下结论因为答案会骗人编译器和断言不会。希望帮到你。本文还有配套的精品资源点击获取