Java中如何避免方法内按引用传递?矩阵类原数据被修改问题
解决Java矩阵类中数组引用传递导致原矩阵被修改的问题
我正在为线性代数课程编写Java矩阵程序,希望每个方法返回新矩阵(基于原矩阵计算)且不修改原矩阵的值,但始终无法避免数组按引用传递的问题。尝试在多处使用a.clone()但结果依旧,请问哪里理解有误?
原程序片段
Matrix类代码
public class Matrix{ private Double[][] data; private String name; public Matrix(Double[][] newdata){ this.data = newdata.clone(); this.name = "default"; } public Matrix scalarMultiply(Double scale){ Matrix output = new Matrix(this.data.clone()); output.name = scale + "(" + output.name + ")"; for(int i = 0; i < output.data.length; i++){ for(int j = 0; j < output.data[i].length; j++){ output.data[i][j] *= scale; } } return output; } }
Main类代码
public class Main { public static void main(String[] args) throws Exception{ new ProcessBuilder("cmd", "/c", "cls").inheritIO().start().waitFor(); Matrix testMatrix = new Matrix(new Double[][]{{1.0, 2.0, 3.0}, {4.0, 5.0, 6.0}, {7.0, 8.0, 9.0}, {100.0, 101.0, 102.0}}); testMatrix.printSpacedAuto(); breakLine(); Matrix testMatrixResult = testMatrix.scalarMultiply(2.0); testMatrixResult.printSpacedAuto(); breakLine(); testMatrix.printSpacedAuto(); testMatrixResult.printSpacedAuto(); breakLine(); } public static void breakLine(){ System.out.println(); } }
问题根源
二维数组的clone()方法是浅拷贝:它只会复制外层数组的引用,里面的每个一维数组仍然和原数组指向同一个对象。也就是说,this.data和传入的newdata虽然是不同的外层数组,但它们的元素(一维数组)是同一个引用,修改新矩阵的元素时,原矩阵的对应元素也会被改动。
解决方案:实现深拷贝
修改Matrix的构造函数,对二维数组进行深拷贝,确保新矩阵的数组和原数组完全独立:
public Matrix(Double[][] newdata) { // 创建外层数组的新实例 this.data = new Double[newdata.length][]; // 逐个复制每个一维数组 for (int i = 0; i < newdata.length; i++) { this.data[i] = newdata[i].clone(); } this.name = "default"; }
修改后,scalarMultiply方法中new Matrix(this.data.clone())里的clone()可以保留(虽然外层数组的拷贝是多余的,但不影响结果),也可以直接写成new Matrix(this.data),因为构造函数已经会完成深拷贝。
验证效果
运行Main类后,原矩阵testMatrix的值不会被scalarMultiply方法修改,返回的testMatrixResult是正确的缩放结果,两者的数据完全独立。
内容的提问来源于stack exchange,提问作者Aidan K
相关产品推荐
相关产品推荐

