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

Java中以接口为类型创建对象的作用及ArrayList两种创建方式差异解析

两种ArrayList创建方式的区别与使用场景

核心区别

两种写法的本质是变量声明的类型不同:

  • 方式1:ArrayList<Integer> myArrayList = new ArrayList<>();
    变量myArrayList的类型是具体实现类ArrayList,它既可以调用List接口定义的通用方法(如add()、get()),也能直接调用ArrayList特有的方法(比如trimToSize()、ensureCapacity())。但后续不能把这个变量赋值为其他List实现类(比如LinkedList)的对象,编译会报错。
  • 方式2:List<Integer> myArrayList = new ArrayList<>();
    变量myArrayList的类型是List接口,它只能调用List接口中定义的方法,无法直接使用ArrayList的独有方法。但好处是后续可以轻松切换成任意List的实现类,比如LinkedList、Vector,代码无需大量修改。

为什么优先用List接口作为类型?

这是面向接口编程的核心思路,核心优势是解耦具体实现,提升代码灵活性和可维护性,结合示例看更清楚:

示例1:实现类切换的灵活性

// 方式2:用List声明
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);

// 业务需求变化,需要换成LinkedList(比如频繁增删头部元素的场景)
nums = new LinkedList<>();
// 后续调用add、get等方法的代码完全不用改
nums.add(3);
System.out.println(nums.get(0));

如果用方式1声明:

// 方式1:用ArrayList声明
ArrayList<Integer> nums = new ArrayList<>();
nums.add(1);

// 这里尝试赋值LinkedList会直接编译报错,必须修改变量类型才能切换
// nums = new LinkedList<>(); // 编译错误

示例2:方法参数的通用性

假设写一个打印列表的方法,用List作为参数类型:

public static void printNumbers(List<Integer> list) {
    for (int num : list) {
        System.out.println(num);
    }
}

// 调用时,ArrayList和LinkedList都能传
ArrayList<Integer> arrayList = new ArrayList<>(List.of(1,2,3));
LinkedList<Integer> linkedList = new LinkedList<>(List.of(4,5,6));
printNumbers(arrayList);
printNumbers(linkedList);

如果方法参数用ArrayList:

public static void printNumbers(ArrayList<Integer> list) {
    for (int num : list) {
        System.out.println(num);
    }
}

// 这里传LinkedList会编译报错,方法只能处理ArrayList,通用性极差
// printNumbers(linkedList); // 编译错误

什么时候用方式1?

只有当你明确需要使用ArrayList特有的方法时,才适合直接声明为ArrayList类型。比如需要手动调整底层数组容量:

ArrayList<Integer> nums = new ArrayList<>();
nums.ensureCapacity(100); // 提前扩容,避免频繁自动扩容
nums.trimToSize(); // 缩小容量到实际元素数,节省内存

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:09:25