package testpro; import java.util.Arrays; /** * 数组的浅拷贝陷阱 * */ public class ArrayDilatation { public static void main(String[] args) { Ball[] balls = new Ball[6]; System.out.println("------------balls------------"+balls); for(int i=0;i<balls.length;i++) { balls[i] = new Ball(i, Color.values()[i]); System.out.println("balls1:"+balls[i]); } Ball[] balls2 = dilatationArray(balls, balls.length); balls2[5].setColor(Color.blue); System.out.println("------------balls2------------"+balls2); for (Ball ball : balls2) { System.out.println("balls2:"+ball); } System.out.println("------------balls------------"+balls); for (Ball ball : balls) { System.out.println("balls1:"+ball); } } public static <T> T[] dilatationArray(T[] datas,int newlen) { //不能为负数 newlen = newlen<0?0:newlen; //生成一个新数组,并copy原值到新数组 return Arrays.copyOf(datas, newlen); } } enum Color{ red,orange,yellow,green,blue,whilt; } class Ball{ private int id; private Color color; public Ball(int id,Color color) { this.id = id; this.color = color; } public int getId() { return id; } public void setId(int id) { this.id = id; } public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } @Override public String toString() { return "Ball [编号=" + id + ", 颜色=" + color + "]"; } }
代码运行结果如下:
------------balls------------[Ltestpro.Ball;@7852e922 balls1:Ball [编号=0, 颜色=red] balls1:Ball [编号=1, 颜色=orange] balls1:Ball [编号=2, 颜色=yellow] balls1:Ball [编号=3, 颜色=green] balls1:Ball [编号=4, 颜色=blue] balls1:Ball [编号=5, 颜色=whilt] ------------balls2------------[Ltestpro.Ball;@4e25154f balls2:Ball [编号=0, 颜色=red] balls2:Ball [编号=1, 颜色=orange] balls2:Ball [编号=2, 颜色=yellow] balls2:Ball [编号=3, 颜色=green] balls2:Ball [编号=4, 颜色=blue] balls2:Ball [编号=5, 颜色=blue] ------------balls------------[Ltestpro.Ball;@7852e922 balls1:Ball [编号=0, 颜色=red] balls1:Ball [编号=1, 颜色=orange] balls1:Ball [编号=2, 颜色=yellow] balls1:Ball [编号=3, 颜色=green] balls1:Ball [编号=4, 颜色=blue] balls1:Ball [编号=5, 颜色=blue]
很明显,改变了balls2这一个数组,结果balls中也跟着被修改了,而且对象引用得地址值也不一样,这种情况就是典型的浅拷贝,用着方便,但是有坑,有风险;为了避免出现这样的情况,我们应该遍历取出balls中的元素,重新生成一个Ball对象然后赋值给balls2中的元素即可;
数组的copyof方法是一个浅拷贝,与序列化的浅拷贝一样:基本类型是直接拷贝值,其他都是拷贝引用地址。数组的clone方法,集合的clone方法也都是浅拷贝,需要特别留意,不要为了少些代码给自己挖坑。