发现问题
我们都知道java.lang.reflect包中的Array类允许动态的创建数组。我们也知道Arrays的copyOf()可以扩展数组长度。那怎么实现这样的通用方法呢?
假如说我们现在有一个Person[]数组a,想到Person[]可以转换为Object[],突然感觉问题就解决了。于是写下了下面的代码:
/**
* @param a 源数组
* @param newLength 新的数组长度
*/
public static object[] badCopyOf(Object[] a, int newLength){
var newArray = new Object[newLength];
System.arrayCopy(a, 0, newArray, 0, Math.min(a.length, newLength));
return newArray;
}
复制代码
然后再强制类型转换,但是报了一个ClassCastException,这个异常的意思是,不能从Object[]强制类型转换为Person[],这就出问题了,如果在其他地方使用这个方法就可能导致安全隐患。所以这种方法是不行的。
解决问题
我们想到Array静态方法newInstance可以构造数组。
Array.newInstance(ComponentType componentType, int newLength);
第一个参数是数组内容类型,第二参数是新数组长度。所以说我们需要做两件事:
- 获得a的类对象(Class对象),确定a是一个数组,然后获得a的内容类型
- 获得源数组长度和newLength比较。
代码如下:
public static Object goodCopyOf(Object a, int newLength){
Class class = a.getClass();
if(!class.isArray())
return null;
Class componentType = class.getComponetType();
int length = Array.getLength(a);
Object newArray = Array.newStance(componentType, newLength);
System.ArrayCopy(a, 0, newArray, 0, Math.min(length, newLength));
return newArrary;
}
复制代码
Array.newInstance方法根据ComponetType构建数组,所以返回的数组类型就是参数a的数组类型。
可能有同学就要问了,“诶,你badCopyOf返回的是Object[],good返回的是Object,有什么讲究吗?”这你仔细想想,基础类型的数组不是Object[]子类,但是是Object的子类,所以为了适用性更好所以就用Object了。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END