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

Java三类ArrayList声明方式差异及接口优先声明的原因

Java集合基础问题解答

问题1:三种ArrayList声明语句的具体差异

三种不会报错的声明语句如下:
a) List l = new ArrayList<String>();
b) List<String> l = new ArrayList<String>();
c) List<String> l = new ArrayList<>();

三者差异如下:

  • 写法a:属于*原始类型(Raw Type)*用法,泛型信息仅在右侧初始化时定义,赋值给原始类型List后,编译器会直接丢失泛型校验能力。后续往列表中插入Integer、Object等非String类型元素都不会触发编译报错,只有运行时才可能抛出类型转换异常,仅在兼容JDK1.5之前的老代码时使用,日常开发完全不推荐。
  • 写法b:是JDK1.5~JDK1.6版本的标准泛型声明写法,左右两侧都明确指定泛型参数为String,编译器会执行完整的类型校验,插入非String类型元素会直接编译报错,类型完全安全。
  • 写法c:是JDK1.7及以上版本推出的*钻石语法(Diamond Operator)*用法,右侧<>中的泛型类型会自动根据左侧变量的泛型类型推断,运行效果和写法b完全一致,仅简化了代码冗余,是当前主流JDK版本中最常用的写法。

问题2:两种集合初始化写法的差异,以及日常开发优先选p的原因

两种写法如下:
p) List<String> l = new ArrayList<String>();
q) ArrayList<String> l = new ArrayList<String>();

核心差异

p是面向接口编程的写法,变量l的类型是List接口;q是面向实现编程的写法,变量l的类型是ArrayList实现类。

优先选择p的原因

  • 降低耦合:后续如果需要替换列表实现,比如要换成支持高频插入的LinkedList、或者不可变列表,只需要修改右侧new后的实现类即可,左侧变量声明、所有调用该变量的上层代码完全不需要改动,符合开闭原则。如果用q的写法,替换实现时需要同时修改变量类型,所有用到ArrayList特有方法的代码都要调整,维护成本极高。
  • 提升灵活性:方法入参、返回值如果定义为List类型,可以兼容所有List接口的实现类,适用范围更广。比如定义一个遍历方法入参为List,调用方不管传ArrayList、LinkedList还是第三方工具包的List实现都可以正常处理,如果入参定义为ArrayList就只能接收这一种实现。
  • 规范编码:用接口类型声明变量,只会暴露List接口定义的通用方法,避免开发者不小心用到ArrayList特有的非通用方法,导致代码和特定实现绑定,后期难以迁移。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.09 04:39:03