最近正在复习Java八股,所以会将一些热门的八股问题,结合ai与自身理解写成博客便于记忆
迭代器的实现原理
迭代器(Iterator)是一种设计模式,提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部表示。
实现原理:
- 迭代器通常作为集合类的内部类实现
- 主要方法包括:
hasNext()
:判断是否还有下一个元素next()
:返回下一个元素remove()
:移除当前元素(可选操作)
- 迭代器维护一个指针来跟踪当前位置
泛型
泛型(Generics) 是JDK 5引入的特性,允许在定义类、接口和方法时使用类型参数。
好处:
- 类型安全:编译时进行类型检查
- 消除强制类型转换
- 代码复用:可以编写更通用的代码
- 更好的可读性:代码中直接体现类型信息
类型擦除(Type Erasure):
- Java泛型是通过类型擦除实现的,编译器在编译时擦除所有类型参数信息
- 编译后,泛型类/方法中的类型参数会被替换为它们的边界类型(无边界则替换为Object)
- 这是为了保持与旧版本Java的二进制兼容性
反射
反射(Reflection) 是指在运行时动态获取类的信息并操作类或对象的能力。
好处:
- 动态创建对象和调用方法
- 运行时分析类的能力
- 实现通用框架和工具
- 突破访问限制(通过setAccessible)
使用场景:
- 框架开发(如Spring的IoC容器)
- 动态代理
- 注解处理
- IDE的代码提示和调试工具
- 测试工具(如JUnit)
动态代理
动态代理是在运行时动态创建代理类和对象的技术。
主要方式:
-
JDK动态代理
- 基于接口
- 使用
java.lang.reflect.Proxy
类 - 原理:运行时生成代理类,实现指定接口并将方法调用转发给InvocationHandler
-
CGLIB动态代理
- 基于继承
- 可以代理普通类
- 原理:通过ASM字节码库在运行时生成目标类的子类
JDK动态代理和CGLIB动态代理的区别:
- JDK代理基于接口,CGLIB基于继承
- JDK代理不需要额外库,CGLIB需要引入ASM库
- JDK代理对接口方法有效,CGLIB可以代理普通方法
- CGLIB不能代理final类和final方法
- CGLIB生成代理类的速度较慢,但运行效率较高
JDK新特性:虚拟线程
虚拟线程(Virtual Threads) 是JDK 19引入的预览特性(在JDK 21中正式发布)。
原理:
- 轻量级线程,由JVM管理,而非操作系统
- 多个虚拟线程映射到少量平台线程(操作系统线程)上
- 当虚拟线程执行阻塞操作时,JVM会自动将其挂起并调度其他虚拟线程运行
- 上下文切换由JVM在用户态完成,开销极小
优势:
- 可以创建大量(数百万)线程而不会导致系统资源耗尽
- 简化高并发编程模型
- 兼容现有Thread API,易于迁移
- 提高资源利用率,特别适合I/O密集型应用
虚拟线程的目标是使编写、调试和维护并发应用程序更容易,同时提高吞吐量。