适配器模式如何分析Arrays.asList将数组变量适配为List接口

来源:AI技术网作者:清原小日向头衔:网络博主
导读:本期聚焦于小伙伴创作的《适配器模式如何分析Arrays.asList将数组变量适配为List接口》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《适配器模式如何分析Arrays.asList将数组变量适配为List接口》有用,将其分享出去将是对创作者最好的鼓励。

适配器模式的核心目标是解决接口不匹配的问题,通过引入一个中间层,将源对象的接口转换为目标接口期望的形式,让原本无法一起工作的类可以正常协作。在Java标准库中,Arrays.asList方法就是适配器模式的经典实践,它完成了数组到List接口的适配工作。

适配器模式如何分析Arrays.asList将数组变量适配为List接口

适配器模式的核心结构

适配器模式通常包含三个核心角色:

  • 目标接口(Target):客户端期望使用的接口,这里是List接口。
  • 适配者(Adaptee):需要被适配的原始对象,这里是普通的数组对象。
  • 适配器(Adapter):实现目标接口,同时持有适配者的引用,完成接口转换逻辑,这里就是Arrays.asList返回的ArrayList内部类。

Arrays.asList的适配实现分析

首先看Arrays.asList的源码实现,它返回的是一个ArrayList实例,但这个ArrayList并不是我们常用的java.util.ArrayList,而是Arrays类的内部私有静态类:

// Arrays类中的asList方法源码
public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}

// Arrays内部静态私有类ArrayList的定义
private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable {
    private final E[] a;

    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }

    @Override
    public int size() {
        return a.length;
    }

    @Override
    public E get(int index) {
        return a[index];
    }

    @Override
    public E set(int index, E element) {
        E oldValue = a[index];
        a[index] = element;
        return oldValue;
    }

    // 注意:没有重写add和remove方法,因此调用会抛异常
}

从源码可以看出,这个内部ArrayList类就是适配器角色:

  • 它实现了List接口(目标接口),因此可以被当作List使用。
  • 它内部持有原始数组a(适配者),所有List接口的方法实现都是基于这个数组完成的。

具体适配逻辑拆解

我们对比数组的原有操作和List接口的方法,看适配是如何完成的:

数组原有操作List接口对应方法适配实现逻辑
获取数组长度arr.lengthsize()返回内部数组a.length
通过下标获取元素arr[index]get(int index)返回a[index]
通过下标修改元素arr[index] = valueset(int index, E element)执行a[index] = element并返回旧值
数组不支持动态添加元素add(E e)未重写父类AbstractList的默认实现,调用会抛UnsupportedOperationException
数组不支持动态删除元素remove(int index)未重写父类AbstractList的默认实现,调用会抛UnsupportedOperationException

适配过程的注意事项

使用Arrays.asList进行适配时,有几个特性需要开发者注意:

  1. 返回的List底层绑定的是原始数组,修改List中的元素会同步修改原始数组,反之亦然:
public class Test {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3};
        List<Integer> list = Arrays.asList(arr);
        // 修改list的元素
        list.set(0, 10);
        System.out.println(arr[0]); // 输出10,原始数组被修改
        // 修改原始数组的元素
        arr[1] = 20;
        System.out.println(list.get(1)); // 输出20,list同步变化
    }
}
  1. List不支持动态扩容,因此不能调用addremove等方法,否则会抛出异常:
public class Test {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 3};
        List<Integer> list = Arrays.asList(arr);
        list.add(4); // 运行时抛出UnsupportedOperationException
    }
}
  1. 如果传入的是基本类型数组,比如int[],会被当作一个单个元素处理,因为泛型不支持基本类型:
public class Test {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3};
        List<int[]> list = Arrays.asList(arr);
        System.out.println(list.size()); // 输出1,整个数组被当作一个元素
    }
}

适配器模式在该场景的价值

如果没有Arrays.asList这个适配器,开发者想要把数组当作List使用,就需要手动编写包装类,实现List接口的所有方法,还要处理数组和List之间的数据同步,成本很高。而JDK通过适配器模式封装了这个逻辑,让开发者只需要一行代码就能完成适配,极大降低了使用成本,也体现了设计模式在实际开发中的实用价值。

适配器模式Arrays.asList数组List接口Java修改时间:2026-06-23 18:03:47

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。