Translate from Simple java
从length和length()开始谈Java
首先,你能快速的回答这个问题吗?
没有任何集成开发环境,如何获得一个数组的长度?又如何获得一个字符串的长度?
我向许多初级和中级的开发者问过这个问题。他们都不能正确或者自信的回答。当IDE提供了便利的代码补全功能时,它同时带来了开发者对问题的“表面理解”。在这里,我将解释一些Java数组的关键概念。
问题答案:
int[] arr = new int[3];
System.out.println(arr.length);//length for array
String str = "abc";
System.out.println(str.length());//length() for string
现在的问题是为什么数组有length这个域而String没有?或者为什么String有length()这个方法而数组没有?
Q1. 为什么数组有length域?
首先,数组是一个包含确定数目的单一类型值的容器。当数组被创建后,它的长度不会再改变。所以数组的length可以作为一个final的域。因此,length可看成数组的一个定义了的属性。
一个数组能用两种方法创建:
1. 数组创建表达式(new)
2. 数组初始化器(直接用{……})
当数组创建时,它的大小是规定好的。
上面的代码已经用过数组创建表达式,它声明了元素的类型,数组的维数,以及至少数组的第一维的长度。
下面的声明变量也是合法的,因为它指定了数组第一维的长度
int[][] arr = new int[3][];
数组初始化器创建数组时提供了所有的元素值。
例如:
int[] arr = {1,2,3};
译者注:
这里可能会有一个疑问,既然数组大小是初始化时就规定好的,那么int[][] arr = new int[3][];
的二维大小不是不确定吗?也就是说arr的大小不是不确定吗?
我们可以用下面的代码观察下arr的大小
int[][] a=new int[3][];
System.out.println(a.length);
int[][] b=new int[3][5];
System.out.println(b.length);
output:
3
3
疑惑的原因是忽略了数组在内存中的存放。java中所有的数组,无论几维,说到底都是一维数组。例如arr,分配了3个空间,每个空间存放一个一维数组的地址,这样就成了“二维”数组。
Q2. 为什么没有像“String”一样存在一个“Array”类?
由于数组也是一个对象,所以下面的代码完全正确
Object obj = new int[10];
一个数组可以包含所有从Object父类继承来的对象(除了clone),那么为什么没有一个array类呢?我们找不到Array.java这个文件,一个简单的粗略的解释是,这些文件被隐藏了。你可以思考这样一个问题——如果有一个Array类,那它会像什么样?它会仍然需要一个数组来存放所有的数组元素,对吗?因此,定义出一个Array类不是一个好的主意。
事实上我们可以获得数组的类,通过下面的代码:
int[] arr = new int[3];
System.out.println(arr.getClass());
输出:
class [I
“class [I”代表着”成员类型是int的数组”的class对象运行时类型的签名
Q3. 为什么String有length()方法?
String其实就是使用char类型的数组来存值的,所以没有必要来定义一个不必要的域。不像C,Java中char的数组并不是一个字符串。