Java中的数组是一维的、固定长度的结构,即在声明时就需要指定数组的长度,在运行时无法更改。而与其相对的是动态数组(Dynamic Array)也称为可调整大小数组(Resizable Array),它是一种支持能够动态增加或缩小容量的数组结构。因此,关于Java数组是否可以改变长度,其实就是在探讨Java是否支持动态数组这一问题。
Java数组长度不可改变的原因
导致Java数组长度不可改变的原因在于,数组在内存中是一个连续的、固定长度的存储区域,数组在声明时就需要占用一定的空间。在Java中,数组的长度是由声明时的元素个数确定的,因此数组的长度是不可变的。
除此之外,Java也没有提供直接改变数组长度的方法或语法。如果试图向数组尾部添加新元素或从数组中删除元素,只能通过创建一个新数组,将旧数组中的数据复制到新数组中,并调整新数组的大小,最后再将新元素添加到新数组中或从新数组中删除指定元素。
Java实现动态数组的方式
虽然Java数组的长度不可改变,但是Java提供了一种数据结构ArrayList,即动态数组(Dynamic Array)的实现方式。ArrayList内部使用Object[]数组来保存数据,它对外暴露的方法比数组灵活多样,可以实现动态添加/删除元素的功能。当ArrayList内部的元素个数超过数组容量时,数组容量就会自动扩容一倍,并将原来的元素复制到新数组中。类似地,当内部元素个数小于数组容量的四分之一时,数组容量就会自动缩小一倍。这种机制使ArrayList能够自适应地扩展或缩小,从而拥有了“动态”的特性。
虽然ArrayList在实现“动态”的过程中需要频繁地创建/销毁数组,但是JVM提供了GC(Garbage Collection)机制来自动回收不在使用的资源,因此这种方式的性能基本可以满足多数应用场景的需求。
结论
Java数组的长度不可改变是由数组固定的内存布局和语言特性所决定的,这一点与其它类C语言相同。但Java提供的动态数组ArrayList,能够支持自适应扩容或缩小容量,使其拥有了动态的特性,同时可以使用ArrayList提供的丰富方法完成添加/删除元素等操作。
因此,当我们需要灵活地操作数据(例如需要频繁添加/删除元素)时,可以使用ArrayList,而对于固定长度的数据(例如矩阵),则应该使用Java的原生数组。