合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
### [动态数组创建](https://lingcoder.gitee.io/onjava8/#/book/06-Housekeeping?id=%e5%8a%a8%e6%80%81%e6%95%b0%e7%bb%84%e5%88%9b%e5%bb%ba) 如果在编写程序时,不确定数组中需要多少个元素,可以使用**new**在数组中创建元素。如下例所示,使用**new**创建基本类型数组。**new**不能创建非数组以外的基本类型数据: ~~~ // housekeeping/ArrayNew.java // Creating arrays with new import java.util.*; public class ArrayNew { public static void main(String[] args) { int[] a; Random rand = new Random(47); a = new int[rand.nextInt(20)]; System.out.println("length of a = " + a.length); System.out.println(Arrays.toString(a)); } } ~~~ 输出: ~~~ length of a = 18 [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] ~~~ 数组的大小是通过`Random.nextInt()`随机确定的,这个方法会返回 0 到输入参数之间的一个值。 由于随机性,很明显数组的创建确实是在运行时进行的。此外,程序输出表明,数组元素中的基本数据类型值会自动初始化为默认值(对于数字和字符是 0;对于布尔型是**false**)。`Arrays.toString()`是**java.util**标准类库中的方法,会产生一维数组的可打印版本。 本例中,数组也可以在定义的同时进行初始化: ~~~ int[] a = new int[rand.nextInt(20)]; ~~~ 如果可能的话,应该尽量这么做。 如果你创建了一个非基本类型的数组,那么你创建的是一个引用数组。以整型的包装类型**Integer**为例,它是一个类而非基本类型: ~~~ // housekeeping/ArrayClassObj.java // Creating an array of nonprimitive objects import java.util.*; public class ArrayClassObj { public static void main(String[] args) { Random rand = new Random(47); Integer[] a = new Integer[rand.nextInt(20)]; System.out.println("length of a = " + a.length); for (int i = 0; i < a.length; i++) { a[i] = rand.nextInt(500); // Autoboxing } System.out.println(Arrays.toString(a)); } } ~~~ 输出: ~~~ length of a = 18 [55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, 51, 89, 309, 278, 498, 361, 20] ~~~ 这里,即使使用 new 创建数组之后: ~~~ Integer[] a = new Integer[rand.nextInt(20)]; ~~~ 它只是一个引用数组,直到通过创建新的**Integer**对象(通过自动装箱),并把对象赋值给引用,初始化才算结束: ~~~ a[i] = rand.nextInt(500); ~~~ 如果忘记了创建对象,但试图使用数组中的空引用,就会在运行时产生异常。 也可以用花括号括起来的列表来初始化数组,有两种形式: ~~~ // housekeeping/ArrayInit.java // Array initialization import java.util.*; public class ArrayInit { public static void main(String[] args) { Integer[] a = { 1, 2, 3, // Autoboxing }; Integer[] b = new Integer[] { 1, 2, 3, // Autoboxing }; System.out.println(Arrays.toString(a)); System.out.println(Arrays.toString(b)); } } ~~~ 输出: ~~~ [1, 2, 3] [1, 2, 3] ~~~ 在这两种形式中,初始化列表的最后一个逗号是可选的(这一特性使维护长列表变得更容易)。 尽管第一种形式很有用,但是它更加受限,因为它只能用于数组定义处。第二种和第三种形式可以用在任何地方,甚至用在方法的内部。例如,你创建了一个**String**数组,将其传递给另一个类的`main()`方法,如下: ~~~ // housekeeping/DynamicArray.java // Array initialization public class DynamicArray { public static void main(String[] args) { Other.main(new String[] {"fiddle", "de", "dum"}); } } class Other { public static void main(String[] args) { for (String s: args) { System.out.print(s + " "); } } } ~~~ 输出: ~~~ fiddle de dum ~~~ `Other.main()`的参数是在调用处创建的,因此你甚至可以在方法调用处提供可替换的参数。