You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中SequencedCollection违反Liskov替换原则?我的理解是否正确?

问题

Java SE 21中新增了SequencedCollection接口,ArrayList、TreeSet等内置集合类都实现了该接口。该接口定义了addLast等方法,使用ArrayList调用addLast可以正常编译并运行:

var myArray = new ArrayList<String>(List.of("a", "b"));
myArray.addLast("c");

但使用TreeSet调用该方法时,代码可以正常编译,却会抛出运行时异常:

var myTree = new TreeSet<String>(List.of("a", "b"));
myTree.addLast("c");

原因是TreeSet虽然实现了SequencedCollection接口,却并不支持addLast方法。这导致接收SequencedCollection类型参数的方法必须通过instanceof判断实际类型,否则会出现意外行为。我认为这违反了SOLID中的Liskov替换原则,请问我的理解是否正确?

回答

你的理解完全正确,这确实违反了Liskov替换原则(LSP)。

Liskov替换原则的核心是:如果一个程序使用的是父类型(这里指SequencedCollection接口),那么替换成任何它的子类型(比如TreeSet)时,程序的行为都应该保持正确,不应该出现意外的异常或不符合预期的结果。

SequencedCollection接口定义了addLast方法,从接口约定的角度来看,调用这个方法应该是一个合法、有效的操作,不会抛出异常。但TreeSet实现该接口后,却在调用addLast时抛出运行时异常,直接打破了这个约定。这就导致客户端代码在仅依赖SequencedCollection接口时,无法安全地使用所有实现类,必须额外做类型判断来规避风险——这完全违背了LSP的设计初衷,因为LSP就是为了让客户端无需关心具体实现,只依赖抽象接口就能正常工作。

内容的提问来源于stack exchange,提问作者Nicolas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 18:34:54