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 是一个新实例,然后对其进行了修改。 B
中 Matrix
的实例根本没有被触及。在函数 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();
抱歉我的初级 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 是一个新实例,然后对其进行了修改。 B
中 Matrix
的实例根本没有被触及。在函数 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();