在本文中,只讨论基本数据类型的数组定义及其相关的操作,并不涉及引用数据类型的操作,以为引用数据类型的机制和基本数据类型数组的机制是有区别的,在后续的博客中会继续深入的讨论。
静态数组格式:
数据类型[] 变量名 = {元素1,元素2,元素3...};
动态数组格式:
数据类型[] 变量名 = new 数据类型[长度]; //必须要给出数组的长度,其中数组的长度可以根据length得到。
静态数组格式:
数据类型[][] 变量名 = {{元素1,元素2...},{元素1,元素2...}...};
动态数组格式:
数据类型[][] 变量名 = new 数据类型[长度1][长度2];
在Java中关于数组的定义有且仅有这两种格式,存在很大的局限性,对于熟悉C/C++的人来说更是难以接受这种定义格式,sun公司也考虑到了这个问题,所以在后面定义了其他的数据结构去补充数组定义带来的不灵活,我们应该接受这种折中,因为Java在很多方面固定格式是为了保证程序的正确性,避免了更大的自由导致的错误。
在Java中出于安全的考虑,不允许程序员操作内存,但是当我们能明确数组究竟在内存中是怎样存储的,对于我们更好的理解Java程序与相当大的好处,在Java中,内存被分为5个部分,但是在数组的存放过程中,仅仅用到其中的两个部分,分别是:栈区和堆区。栈区存储的仅仅在作用域内有效,一旦出了作用域立马就会销毁,但是堆区的数据却不是根据作用域来释放的,在C/C++中需要程序员手动去释放堆区的内存,否则会导致内存的泄露,而我们在敲代码的过程中经常会忘记去释放内存,同样,sun公司为了弥补这个缺陷,利用了一个垃圾回收器,当堆区中出现没有被引用的对象时,会在合适的时间调用垃圾回收器回收空间,避免了程序员因不能及时回收空间导致堆区空间耗尽,影响后面程序的运行,这是JVM的职责,关于垃圾回收器究竟是什么,会在以后的博客中深入的说明,现在并不适合去说明JVM的机制。http://www.linuxidc.com/Linux/2013-03/81800.htm 参考这篇文章,讲的还是不错的,我不想画图了,所以略去吧,尤其对于熟悉C/C++内存分配的程序员,我想你们应该更能理解这个内存表示的原因,并能看出其本质究竟是什么。
数组下标越界是一个经常会遇到的问题,请自行控制你的程序,通过debug可以跟踪这个bug。
public class TestPoint{
public static void main(String[] args){
int[] arr = {1,3,5};//定义个一个静态数组
arr = null;//也就是将arr的地址清空
System.out.print(arr[0]);//这个句子就是所谓的空指针异常,这段代码在编译时会发生错误,arr已经没有指向{1,3,5}这个堆区空间了,但是仍然使用了arr[0]
}
}
public static void fun(int...arr)//定义一个可变长度参数
{
for(int i = 0 ; i < arr.length; i++){
System.out.println(arr[i]) //在这里我们实际把它当做了数组使用
}
}
关于可变长度参数有几点说明:
* 可变长度参数必须是函数的最后一个参数;
* 可变长度参数实际上就是数组的语法糖,在调用有可变长度参数的函数时,完全可以将数组作为实参。
那么sun公司为了要定义可变长度参数呢?我在前面说过,Java中的数组很不自由,从数组的两种定义方式中我们可以看出,在定义数组的时候,必须给出数组的长度,但是很多情况下,我们很难确定数组的长度究竟是多少,所以sun公司为了弥补数组的这个缺陷,同时也为了与C++抗衡(你说不抗衡我不信,毕竟C++也拥有那么大的市场份额),在C++中有可变长度参数,Java也要有这个功能,同时还弥补了Java数组的缺陷,一举两得,何乐而不为?
但是在很多情况下我不建议广大的程序员使用可变长度参数类型,因为这样至少存在一个缺陷是:慢,为什么会慢?因为实际上可变长度参数是数组的语法糖,所以在编译运行的过程中,实际上JVM必须将这个语法糖转换为真正的数组,这用中国人的话来讲是脱裤子放屁,多此一举啊。
如果非要使用数组的语法糖,也不是不可以,在这种情况下,Java的程序员会同时使用for循环的语法糖,使这个代码的逻辑更加的简单,for语法糖的例子如下(还是操作上面那哥可变长度参数的例子):
for(int num:arr){
System.out.println(num);//同样能打印出这个数组的值
}
二维数组的for循环语法糖:
int[][] arr = {{1,2},{3,4},{4,5,6}}
for(int[] level_1:arr){
for(int num:level_1){
System.out.println(num); //同样能实现输出的效果
}
请查阅JDK中:java.util.Arrays,其中关于数组的很多操作,在这个类中都有详细的定义,许多函数都进行了不同数据类型的重载,例如数组的排序、二分查找等。