尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

java面试基础知识点(2)

java面试基础知识点(2) 第一章 java基础语法1.4 抽象类 vs 接口1.4.1 JDK8 接口的 default 方法JDK8 引入 default 方法是为了在给接口添加新方法时不影响已有的实现类向后兼容。interfaceVehicle{// 抽象方法 — 实现类必须实现voidrun();// default方法 — 实现类可选择重写defaultvoidhorn(){System.out.println(Beep beep!);}// static方法 — 属于接口通过接口名调用staticStringgetType(){returnTransport;}}classCarimplementsVehicle{Overridepublicvoidrun(){System.out.println(Car is running);}// horn() 可以不重写使用接口默认实现}// 钻石问题多继承冲突interfaceA{defaultvoidfoo(){System.out.println(A);}}interfaceB{defaultvoidfoo(){System.out.println(B);}}classCimplementsA,B{Overridepublicvoidfoo(){// 必须重写编译器报错A.super.foo();// 可以选择调用A的实现}}1.5 异常体系1.5.1异常基本继承体系Java异常体系的根类是 Throwable下分两个子类Error 和 Exception。ErrorJVM层面的严重错误如 OutOfMemoryError、StackOverflowError程序无法处理不应 try-catch。Exception程序可以捕获处理的异常分为两大类●受检异常Checked Exception编译时必须处理throws 声明或 try-catch如 IOException、SQLException、ClassNotFoundException●非受检异常Unchecked Exception运行时异常 RuntimeException 及其子类编译时不强制处理如 NullPointerException、ArrayIndexOutOfBoundsException、IllegalArgumentException// 异常处理最佳实践publicclassExceptionDemo{// 1. try-with-resourcesJDK7自动关闭资源publicstaticStringreadFile(Stringpath){try(BufferedReaderbrnewBufferedReader(newFileReader(path))){returnbr.readLine();}catch(IOExceptione){// 2. 记录日志不要吞掉异常log.error(读取文件失败: {},path,e);thrownewRuntimeException(文件读取异常,e);// 包装为运行时异常}// 3. finally 不需要手动 closetry-with-resources 自动处理}// 4. finally 不执行的情况面试题publicstaticinttestFinally(){try{return1;}catch(Exceptione){return2;}finally{return3;// ⚠️ 最终返回3finally中的return会覆盖try/catch的return}}// 5. try-catch-finally 执行顺序publicstaticinttest(){try{System.out.println(try);System.exit(0);// 唯一阻止finally执行的方式return1;}finally{System.out.println(finally);// 不会打印JVM已退出}}}面试高频① try-catch-finally 的执行顺序finally总是执行除非System.exit()或JVM崩溃② try-with-resources 的原理实现 AutoCloseable 接口③ 自定义异常继承 Exception 或 RuntimeException1.5.2try-catch疑难点finally 一定会执行吗绝大部分情况会执行唯一例外System.exit(0)在 try/catch 中直接退出 JVMfinally不会执行。try 或者 catch 里有 returnfinally 还执行吗执行顺序会执行流程执行到 return先把返回值保存先执行 finally 代码再执行真正 return1.6 泛型Generics泛型是 JDK5 引入的参数化类型机制允许在定义类、接口、方法时使用类型参数编译时进行类型检查。1.6.1 类型擦除核心概念Java 泛型通过类型擦除Type Erasure实现 —— 编译器在编译阶段擦除泛型类型信息将类型参数替换为上限类型默认 Object并在必要处插入强制类型转换。这意味着泛型信息在运行时不可用。// 编译前ListStringlistnewArrayList();list.add(hello);Stringslist.get(0);// 编译后类型擦除ListlistnewArrayList();// 泛型信息被擦除list.add(hello);Strings(String)list.get(0);// 编译器自动插入强制转换// 类型擦除的证据ListStringlist1newArrayList();ListIntegerlist2newArrayList();System.out.println(list1.getClass()list2.getClass());// true! 都是 ArrayList.class1.6.2 通配符与PECS原则PECS 原则Producer Extends, Consumer Super? extends T上界通配符只能读取不能写入生产者适用于从集合中获取数据? super T下界通配符只能写入不能读取消费者适用于向集合中添加数据// 上界通配符 ? extends TList?extendsNumbernumbersnewArrayListInteger();Numbernnumbers.get(0);// ✅ 读返回Number类型// numbers.add(1); // ❌ 写编译错误不知道具体是哪种Number子类// 下界通配符 ? super TList?superIntegerlistnewArrayListNumber();list.add(100);// ✅ 写可以添加Integer及其子类Objectobjlist.get(0);// ⚠️ 读只能返回Object丢失类型信息// 无界通配符 ?List?wildListnewArrayListString();// wildList.add(a); // ❌ 不能写ObjectowildList.get(0);// ✅ 只能读回Object// PECS实际应用Collections.copypublicstaticTvoidcopy(List?superTdest,List?extendsTsrc){// dest是消费者(写入) → super// src是生产者(读取) → extendsfor(Titem:src){dest.add(item);}}1.7 反射机制Reflection反射允许程序在运行时获取类的完整信息类名、方法、字段、注解等并动态操作对象。它是框架Spring、MyBatis的基石。1.7.1 获取 Class 对象的三种方式// 方式1类名.class — 最常用ClassStringclazz1String.class;// 方式2对象.getClass() — 有实例时使用Stringstrhello;Class?clazz2str.getClass();// 方式3Class.forName() — 动态加载类JDBC驱动加载就用这个Class?clazz3Class.forName(java.lang.String);// 三者返回的是同一个Class对象System.out.println(clazz1clazz2);// trueSystem.out.println(clazz2clazz3);// true1.7.2 反射常用APIpublicclassReflectDemo{publicstaticvoidmain(String[]args)throwsException{Class?clazzClass.forName(com.example.User);// 1. 创建实例Objectobjclazz.getDeclaredConstructor().newInstance();// 2. 获取并操作字段FieldnameFieldclazz.getDeclaredField(name);nameField.setAccessible(true);// 绕过 private 限制nameField.set(obj,张三);// 3. 获取并调用方法MethodsetNameclazz.getMethod(setName,String.class);setName.invoke(obj,李四);MethodgetNameclazz.getMethod(getName);Stringname(String)getName.invoke(obj);System.out.println(name);// 李四// 4. 获取所有方法和字段Method[]methodsclazz.getDeclaredMethods();// 所有方法含privateField[]fieldsclazz.getDeclaredFields();// 所有字段含private// 5. 获取并调用构造方法Constructor?constructorclazz.getConstructor(String.class,int.class);Objectuserconstructor.newInstance(王五,25);}}1.9 I/O 流与 NIOJava I/O 是数据输入输出的基础分为 BIO阻塞I/O、NIO非阻塞I/O和 AIO异步I/O。1.9.1 字节流 vs 字符流1.9.2 装饰器模式在 I/O 中的应用Java I/O 使用了经典的装饰器模式。基类组件提供基本功能装饰器类通过组合方式动态添加额外功能缓冲、数据转换等。// 装饰器模式在I/O中的体现// FileInputStream 是被装饰的组件提供基本的字节读取// BufferedInputStream 是装饰器添加缓冲功能// DataInputStream 是另一层装饰器添加读取基本类型的功能DataInputStreamdisnewDataInputStream(newBufferedInputStream(newFileInputStream(data.bin)));intnumdis.readInt();// 读取一个intdoubleddis.readDouble();// 读取一个double// 每个装饰器都有各自的职责可以灵活组合
返回列表