Java数组未改动值异常变更:遗传算法绘图问题排查
问题分析与解决方案
嘿,我帮你捋捋这个问题!你在做三角形重绘图像的遗传算法时,populate方法生成子代居然意外改了父代的值,这个坑我之前也踩过,大概率是对象引用共享搞的鬼。
为啥父代会被修改?
看你代码里的triangles[drawNum][triNum] = triangles[0][triNum]这句,在Java里,对象类型的赋值传的是引用地址,不是对象本身。也就是说,子代数组里的这个位置和父代triangles[0][triNum]指向的是同一个三角形对象!后面你要是改子代的这个三角形(比如调顶点坐标、颜色),父代的那个对象肯定跟着变——因为它们根本就是同一个东西呀。
怎么 fix 这个问题?
你得给子代做深拷贝,也就是创建一个全新的三角形实例,把父代三角形的所有属性值都复制到新对象里,而不是直接搬引用。
举个实际的例子,假设你的三角形类是Triangle,我给你写个可行的方案:
- 先给
Triangle加个拷贝构造函数,专门用来复制对象:
public class Triangle { // 假设你的三角形有这些属性 private double x1, y1, x2, y2, x3, y3; private Color color; // 拷贝构造函数:把传入的Triangle的所有属性复制过来 public Triangle(Triangle original) { this.x1 = original.x1; this.y1 = original.y1; this.x2 = original.x2; this.y2 = original.y2; this.x3 = original.x3; this.y3 = original.y3; // 颜色也要深拷贝,不然Color对象还是共享引用 this.color = new Color(original.color.getRGB()); } // 你的其他构造函数、getter/setter啥的... }
- 然后把
populate里的赋值语句改成用拷贝构造函数创建新对象:
// 原来的浅拷贝(坑人的那句) // triangles[drawNum][triNum] = triangles[0][triNum]; // 改成深拷贝,生成独立的新对象 triangles[drawNum][triNum] = new Triangle(triangles[0][triNum]);
额外要注意的点
- 如果你的三角形用数组存属性(比如
double[] vertices),那数组本身也要深拷贝,比如用Arrays.copyOf(original.vertices, original.vertices.length),不能直接赋值数组引用。 - 检查后续对子代三角形的修改逻辑,确保所有操作都是在新创建的对象上进行,别不小心碰了父代的对象。
这样改完之后,子代和父代的三角形就是完全独立的个体了,再修改子代就不会影响父代啦!
内容的提问来源于stack exchange,提问作者Josh Czopek
相关产品推荐
相关产品推荐

