Java,clone()问题?

时间:2016-08-24 08:49:57

标签: java reference copy clone

对不起我的基本Java问题。有以下课程

public class Matrix {

    public final double[][] items;
    private final int rows_count,  columns_count;

    public Matrix( final int rows_count_, final int columns_count_)   {
        rows_count = rows_count_; columns_count = columns_count_;
        items = new double[rows_count][columns_count];
    }

    public Matrix(final double[][] data)  {
            rows_count = data.length;
            columns_count = data[0].length;
            items = new double[rows_count][columns_count];
            for (int i = 0; i < rows_count; i++)
                    for (int j = 0; j < columns_count; j++)
    }

    public Matrix copy () {
            Matrix AC = new Matrix(rows_count, columns_count);
            for (int i = 0; i < rows_count; i++) 
                    for (int j = 0; j < columns_count; j++) 
                            AC.items[i][j] = items[i][j];
            return AC;
    }

    public Matrix clone ()  { return this.copy }

    public void test (Matrix B)        {
            B = this.clone();
            B.items[0][0] = 1;
    }

在方法测试中,完成以下分配

B = A

致电

    double[][] d = { { 1, 2, 3 }, { 4, 5, 6 }, { 1, 0, 1} };
    Matrix A = new Matrix(d);
    Matrix B= new Matrix(3,3);
    A.test(B);
    B.print();

结果令人惊讶。尽管

 B = this.clone()

得到的B矩阵为零。

0.0 0.0 0.0 
0.0 0.0 0.0 
0.0 0.0 0.0 

看起来B传递的值是:-)重写test()以便

    public void test (Matrix B)        {
            B.items[0][0] = 1;
    }

矩阵B被正确修改

1.0 0.0 0.0 
0.0 0.0 0.0 
0.0 0.0 0.0 

问题出在哪里,可能写错了复制/克隆方法?如何解决问题并执行任务B = A?谢谢你的帮助。

2 个答案:

答案 0 :(得分:1)

问题是,clone返回一个新实例,然后进行修改。 MatrixB的实例根本没有触及。在函数返回后,为函数的参数分配新值不会更改传递的变量,并且所有更改都将丢失。您必须更改传递的对象,而不是保存它的变量,以便在函数外部存档更改。

要更改B,您可以更改test方法以返回B,然后将其重新分配到外面(这会使其失效)。

另一种方法是使copy函数以Matrix作为参数,然后使用新日期更新它(不创建新的Matrix)。旧的copy甚至可以通过首先创建一个新的Matrix然后将其传递给新的copy来使用此新功能。

编辑:关于提及C ++和指针的评论:在C ++(以及许多其他语言)中,您可以将指针传递给函数。如果这样做,重新分配实际上会将传递的变量更改为函数外部。在Java中,这是不可能的(据我所知)。您可以在this question

中找到有关此主题的更多信息

答案 1 :(得分:1)

Object class有一种clone()方法。您可以使用它而不会覆盖它。为了能够使用它,您需要确保上课implements Cloneable

public class Matrix implements Cloneable {
    //...
}