Java Queue接口四组方法体现强弱契约:add()/offer()处理满队列(抛异常/返回false),remove()/poll()处理空队列(抛异常/返回null),element()/peek()访问头元素(抛异常/返回null),选型取决于是否需异常中断流程。

Java 中 Queue 接口的这四组方法本质是同一操作的两种容错策略:一个倾向“强契约”(失败就报错),另一个倾向“弱契约”(失败就返回特殊值)。
offer() 和 add():添加元素时,满队列怎么处理?
两者都向队尾插入元素,区别只在队列已满时的反应:
-
add():立即抛出
IllegalStateException(例如用ArrayBlockingQueue且容量已满时) -
offer():不抛异常,直接返回
false,调用方自行判断是否重试或降级
实际开发中,只要队列有容量限制(如阻塞队列、有界队列),优先用 offer();只有确定永远不满(比如无界 LinkedList 作 Queue),add() 才不会出问题。
poll() 和 remove():删除头元素时,空队列怎么处理?
两者都移除并返回队头元素,区别只在队列为空时的反应:
-
remove():抛出
NoSuchElementException -
poll():安静返回
null
如果你的逻辑里可能遇到空队列(比如多线程消费、定时轮询),用 poll() 更安全;如果业务上“空队列删元素”属于程序逻辑错误(比如初始化没做对),remove() 能更快暴露问题。
顺带提一下 element() 和 peek()
这两个是“只看不删”的头元素访问方法,行为模式一致:
-
element():队列为空 → 抛
NoSuchElementException -
peek():队列为空 → 返回
null
和上面两组一样,peek() 更常用,尤其在检查是否有待处理任务但不想改变队列状态时。
核心就两点:要不要让异常中断流程,还是自己用返回值控制逻辑走向。选哪个,取决于你愿不愿意为边界情况写 try-catch,或者更信任自己对队列状态的判断。










