/**
* 反射中的 reflect包中的Array类允许动态创建数组
* 这个特性被用到了Array类中的copyOf方法实现中,下面是例子
*
* Employee[] a = new Employee[100];
* …(数组已经填满)
* a = Arrays.copyOf(a,2*a.length);
*
* 下面编写的是通用的copy方法
*
* 向上造型,是把低级的类型变成高级类型,
* 比如Employee[] 可以转换成Object[],再转换回 Employee[]
* 因为此时的Object[] 知道他是 Employee[] 的
* 向下造型,只有 Object[] 知道它接收的是 Employee[],才能向下造型
*
* 所以
* 下面好的copy方法和坏的copy方法区别在于,好的copy方法能让Object知道自己接受的是上面类型
* 注意:
* int[]数组可以转换成Object,却不能转换成Object[]
* 所以下面的返回类型选择Object(也就是收如果不打算用到int[],可以用Object[]作为返回类型的)
* 不过似乎Object能接受的更大?
*/
import java.lang.reflect.Array;
import java.util.Arrays;
public class test4 {
public static void main(String[] args) {
int[] a = { 1, 2, 3 };
a = (int[]) goodCopOf(a, 10);// 返回的时object类型
System.out.println(Arrays.toString(a));
String[] b = { "Tom", "Dick", "Harry" };
b = (String[]) goodCopOf(b, 10);
System.out.println(Arrays.toString(b));
System.out.println("The following call will generate an exception.");
// b 是 String[],可以向上造型 Object,并且可以继续再向下造型回来
// 但是b传进 badCopyOf 后,返回的是Object,这个 Object 并不是String[]向上造型得到的
// 所以 这个 Object 无法向下造型成String[]
// 因此这是一个不好的copy方法
b = (String[]) badCopyOf(b, 10);
}
public static Object[] badCopyOf(Object[] a, int newLength) {
Object[] newArrry = new Object[newLength];
System.arraycopy(a, 0, newArrry, 0, newLength);
return newArrry;
}
public static Object goodCopOf(Object a, int newLength) {
// 1.获得a数组的类对象
Class cl = a.getClass();
// 2.确认他是一个数组
if (!cl.isArray())
return null;
// 使用 getComponentType 获取数组类型
Class componentType = cl.getComponentType();
// 用 Array.getLength 获取数组长度
int length = Array.getLength(a);
// 用 Array.newInstance 创建新的数组,填入参数:类型 + 长度
Object newArray = Array.newInstance(componentType, newLength);
// System.arraycopy 复制数组内容到新的数组
System.arraycopy(a, 0, newArray, 0, Math.min(length, newLength));
return newArray;
}
}
结果:
[1, 2, 3, 0, 0, 0, 0, 0, 0, 0]
[Tom, Dick, Harry, null, null, null, null, null, null, null]
The following call will generate an exception.
Exception in thread "main" java.lang.ClassCastException: class [Ljava.lang.Object; cannot be cast to class [Ljava.lang.String; ([Ljava.lang.Object; and [Ljava.lang.String; are in module java.base of loader 'bootstrap')
at test4.main(test4.java:46)