Java,克隆()问题?

Java, clone() problems?

抱歉我的初级 Java 问题。有以下class

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 

哪里有问题,可能是copy/clone方法写错了?如何解决问题并执行分配 B = A?感谢您的帮助。

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

要更改 B,您可以将 test 方法更改为 return B,然后在外部重新分配它(这会使传递它无用)。

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

来使用这个新函数

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

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

有个clone() method of the Object class. You could use it without overriding it. To be able to use it, you need to make sure you class implements Cloneable.

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

您的 test() 方法的问题在于它没有 return 任何对象,因此不会在方法之外进行任何更改。

Public无效测试(矩阵 B) B 在这种情况下是一个局部变量,这意味着它的生命周期从启动方法开始,到方法结束时结束。 Java 是 CallByValue 而不是 CallByReference,这意味着您不会在方法内部传递实际的对象引用,而是传递具有相同值的新引用,如副本。

B=this.clone(); 尽管您为 B 分配了 A 的克隆,但 B 仍然仅在该方法内部可用,并且不会影响您传递给该方法的 B 实例。

B.items[0][0] = 1; //你仍然只是改变了 B 的内部(局部)变量,而不是 B 的原始实例。因为你没有 return B,所以这个方法中的所有更改都已过时,B 将被丢弃。

为了让你的方法起作用,你应该这样设计它:

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

然后你需要把这个Method的调用再分配给B,像这样:

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