# Java
68 篇文章与「Java」相关的全部文章。
什么是 fail-fast 机制?
一、定义 在用迭代器遍历集合时,如果集合结构被修改(增/删),迭代器会立即抛出 ConcurrentModificationException,这就是 fail-fast。 二、实现原理 集合内部维护 modCount 记录结构修改次数。迭代器创建时记录 expectedModCount = mod
HashSet 和 TreeSet 的区别?
一、底层实现 HashSet:内部是 HashMap,元素作为 HashMap 的 key,value 是固定 Object。 TreeSet:内部是 TreeMap,基于红黑树。 二、对比 维度 HashSet TreeSet 有序性 无序 自然排序或定制排序 元素要求 重写 equals/has
ConcurrentHashMap 如何保证线程安全?
一、JDK 1.7:分段锁 内部是 Segment 数组,每个 Segment 是一个小 HashMap,put 时只锁当前 Segment,并发度 = Segment 数(默认 16)。 二、JDK 1.8:CAS + synchronized 数组节点为空时,用 CAS 插入,无锁。 节点不为空
HashMap 的底层实现原理?
一、数据结构 JDK 1.8 后 HashMap = 数组 + 链表 + 红黑树。 数组是主体,通过 (n-1) & hash 定位桶。 哈希冲突时,同桶元素挂成链表。 链表长度 ≥ 8 且数组长度 ≥ 64 时,链表转红黑树;节点数 ≤ 6 时转回链表。 二、put 流程 计算 key 的 has
ArrayList 和 LinkedList 的区别?
一、底层结构 ArrayList:基于动态数组,连续内存存储。 LinkedList:基于双向链表,节点分散存储。 二、性能对比 操作 ArrayList LinkedList 随机访问 O(1) O(n) 尾部追加 O(1)(均摊) O(1) 中间插入/删除 O(n)(需移动元素) O(1)(定位
接口和抽象类有什么区别?
一、核心区别 维度 抽象类 接口 关键字 abstract class interface 继承 单继承 多实现 构造方法 有 无 成员变量 任意 仅 public static final 方法实现 可有抽象/具体方法 默认方法、静态方法(JDK 8+) 设计目的 "is-a" 共性抽取 "can
重载(overload)和重写(override)的区别?
一、定义 重载:同一个类中,方法名相同,参数列表(类型/个数/顺序)不同。与返回值无关。 重写:子类重新实现父类的方法,方法签名(名称、参数、返回值)必须一致。 二、对比 维度 重载 重写 位置 同类 父子类 参数列表 必须不同 必须相同 返回值 可不同 相同或协变 权限 可不同 不能更严格 绑定时
final 关键字有哪些用法?
一、修饰类 final 修饰的类不能被继承,如 String、Math。常用于工具类或不希望被扩展的类。 二、修饰方法 final 方法不能被子类重写,防止子类改变父类行为。构造方法隐式为 final。 三、修饰变量 成员变量:必须在声明时、构造方法或初始化块中赋值,赋值后不可改。 局部变量:使用前
String 为什么是不可变的?
一、不可变的体现 String 内部用 final char[](JDK 9 后是 byte[])存储字符,且没有提供修改内部数组的方法,一旦创建内容就不能改。所谓"修改"其实是创建新对象。 二、设计原因 字符串常量池复用:相同字面量共享同一对象,节省内存。 线程安全:不可变对象天然线程安全,多线程
int 和 Integer 有什么区别?
一、本质区别 int 是 Java 的 8 种基本数据类型之一,直接存数值,占 4 字节,默认值 0。 Integer 是 int 的包装类,是对象,存的是指向堆中对象的引用,默认值 null。 二、自动装箱与拆箱 Integer a = 10; // 自动装箱:Integer.v
为什么重写 equals 时一定要重写 hashCode?
一、先说结论 这是 Java 的通用约定:如果两个对象通过 equals 比较相等,那么它们的 hashCode 必须相同。只重写 equals 不重写 hashCode,会破坏这个约定,导致对象在 HashMap、HashSet 等集合中行为异常。 二、HashMap 的存取过程 HashMap
String、StringBuilder 和 StringBuffer 的区别?
一、可变性不同 String 是不可变类,内部用 final 修饰字符数组。对字符串做拼接实际上会创建新的 String 对象。 StringBuilder 与 StringBuffer 都继承自 AbstractStringBuilder,内容可变,拼接时直接修改内部数组。 二、线程安全不同 St
== 和 equals 的区别是什么?
一、== 的作用 == 是 Java 的运算符,它的比较规则取决于两边的类型: 基本数据类型(byte、short、int、long、float、double、char、boolean):比较的是字面值是否相等。 引用数据类型:比较的是两个引用是否指向堆中的同一个对象(即内存地址是否相同)。 int
Lombok 主要作用是什么?它是干嘛的?
Lombok 是一个超酷的 Java 库,它能让你的 Java 代码变得简洁、高效,还能帮你省去很多繁琐的工作,堪称偷懒神器,企业级开发必备。
Lombok @SneakyThrows 注解:简化异常操作
@SneakyThrows 用来偷偷地抛出检查型异常(checked exception),而无需显式地在方法签名中声明 throws 或者使用 try-catch。对于需要捕获或声明的异常,@SneakyThrows 注解可以让方法绕过这一步。
Lombok @Value 注解:创建不可变类
Lombok 的 @Value 注解用于简化不可变对象的创建。不可变对象(Immutable Object)在创建后,其内部状态无法改变,具备线程安全的特性,适合并发环境中共享数据的场景。
Lombok @ToString 注解:快速打印对象内容
Lombok 的 @ToString 注解用于自动生成 toString() 方法,帮助快速打印对象的内容,以便调试或日志记录。默认情况下,`@ToString` 会将类中所有非静态字段包含在 toString() 方法中,并按字段声明的顺序显示字段值。
Lombok 实现原理是什么?
Lombok 的核心是利用 Java 注解处理器 和 AST(抽象语法树)修改 技术,在编译阶段动态插入代码。
Lombok @Log 系列注解: 简化日志记录
Lombok 提供了一系列 @Log 注解,用于自动生成日志记录器实例,简化 Java 类中日志的定义和使用。这些注解支持常见的日志框架,比如 java.util.logging、Log4j、Log4j2、Slf4j 等。
Lombok @Getter @Setter 注解: 简化属性操作
Lombok 提供的 @Getter 和 @Setter 注解是最常用的注解之一,主要用于自动生成类的 getter 和 setter 方法。这些方法可以大大减少手动编写代码的工作量,让代码更简洁、更易读。
