(一)创建一个非基本类型数组(引用数组)
例如:
import java.util.Arrays;
import java.util.Random;
public class ArrayClass {
public static void main(String[] args) {
Random rand = new Random(47);
Integer[] a = new Integer[rand.nextInt(20)]; // 自动包装机制
System.out.println(a.length);
for (int i = 0; i < a.length; i++) {
a[i] = rand.nextInt(500);
}
System.out.print(Arrays.toString(a));
}
}
结果如下:
18
[55, 193, 361, 461, 429, 368, 200, 22, 207, 288, 128, 51, 89, 309, 278, 498, 361, 20]
也可以用花括号括起来的列表初始化对象数组 :
import java.util.Arrays;
public class ArrayInit {
public static void main(String[] args) {
Integer[] a = { new Integer(1), new Integer(2) };
Integer[] b = new Integer[] { new Integer(1), new Integer(2) };
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
}
}
结果如下:
[1, 2]
[1, 2]
甚至是在方法调用的内部。例如:可以创建一个String对象数组,将其传递给另一个main方法,以提供参数,用来替换传递给main()方法命令行参数:
class Other {
public static void main(String[] args) {
for (String s : args) {
System.out.println(s + "\t");
}
}
}
public class DynamicArray {
public static void main(String[] args) {
Other.main(new String[] { "a", "b", "c" });
}
}
结果如下:
a
b
c
(二)可变参数列表
(1)所有的类都直接或间接继承于Object
(2) 用Object数组作为参数,foreach遍历输出
(3) 对于类的对象,打印内容为:类名+@+十六进制数字
例如:
class A {
}
public class VarArgs {
static void printArray(Object[] args) {
for (Object obj : args)
System.out.print(obj + "\t");
System.out.println();
}
public static void main(String[] args) {
printArray(new Object[] { new Integer(1), new Float(1.1), new Double(11.11) });
printArray(new Object[] { "123", "345", "456" });
printArray(new Object[] { new A(), new A(), new A() });
}
}
结果如下:
1 1.1 11.11
123 345 456
num5.A@70dea4e num5.A@5c647e05 num5.A@33909752
``JavaSE5之后,加入了新特性,可以定义可变参数列表:
例如:
public class NewVarArgs {
static void printArray(Object... args) {
for (Object obj : args)
System.out.print(obj + "\t");
System.out.println();
}
public static void main(String[] args) {
printArray(new Integer(1), new Float(1.1), new Double(11.11));
printArray("123", "345", "456");
printArray(new A(), new A(), new A());
printArray((Object[]) new Integer[] { 1, 2, 3, 4 });//Iteger->Object(以便消除编译器警告),编译器会发现它已经是一个数组了,不会在其上执行任何转换
printArray();
}
}
结果如下:
1 1.1 11.11
123 345 456
num5.A@70dea4e num5.A@5c647e05 num5.A@33909752
1 2 3 4
在可变参数列表中可以使用任何类型的参数,包括基本类型。如果在该列表中没有任何元素,那么转变城的数据的尺寸为0:
例如:
public class VarargType {
static void f(Character... args) {
System.out.print(args.getClass());
System.out.println(args.length);
}
static void g(int... args) {
System.out.print(args.getClass());
System.out.println(args.length);
}
public static void main(String[] args) {
f('a');
f();
g(1);
g();
System.out.println(new int[0].getClass());
}
}
结果如下:
class [Ljava.lang.Character;1
class [Ljava.lang.Character;0
class [I1
class [I0 //【: 表示这是后面一个紧随的类型的数组,I 表示基本类型为Int
class [I //int数组 验证了使用可变参数列表不依赖于自动包装机制,而实际上使用的是基本类型
可变参数列表与自动包装机制可以和谐共处:
public class AutoboxingVarargs {
public static void f(Integer... args) {
for (Integer i : args)
System.out.print(i + " ");
System.out.println();
}
public static void main(String[] args) {
f(new Integer(1), new Integer(2));
f(4, 5, 6, 7, 8);
f(10, new Integer(11), 12);
}
}
结果如下:
1 2
4 5 6 7 8
10 11 12 //可在参数列表中将类型混合在一起,而自动包装机制将有选择的将int参数提升为Integer
应该最好只在一个方法中使用可变参数列表,若都用,应在两个方法上都添加一个非可变参数:
public class OverLoading {
static void f(char c, Character... args) {
System.out.print("first");
for (Character cc : args) {
System.out.println(" " + cc);
}
}
static void f(float f, Character... args) {
System.out.print("first");
for (Character c : args) {
System.out.println(" " + c);
}
}
public static void main(String[] args) {
f('a', 'b');
f(1, 'a');
}
}
结果如下:
first b
first a