令人费解的行为(Java实例、数组和GWT)
我不确定这是Java行为还是恶意GWT行为。但事情是这样的 我有一个2D向量的类,叫做Vector2。在我的程序中,我对此类实例表示的2D粒子进行了一些模拟。我有两个向量2数组,m_x和m_oldx,它们是另一个类的成员,有一个函数可以进行一些处理。这个函数的一部分如下所示,我对它的行为感到非常困惑:令人费解的行为(Java实例、数组和GWT),java,arrays,gwt,instance,Java,Arrays,Gwt,Instance,我不确定这是Java行为还是恶意GWT行为。但事情是这样的 我有一个2D向量的类,叫做Vector2。在我的程序中,我对此类实例表示的2D粒子进行了一些模拟。我有两个向量2数组,m_x和m_oldx,它们是另一个类的成员,有一个函数可以进行一些处理。这个函数的一部分如下所示,我对它的行为感到非常困惑: Vector2 old = m_x[i]; Vector2 test = new Vector2(9.0f,9.0f); m_x[i] = test; // 1: at this point,
Vector2 old = m_x[i];
Vector2 test = new Vector2(9.0f,9.0f);
m_x[i] = test;
// 1: at this point, m_x[i]'s values are 9.0,9.0
m_oldx[i] = old;
// 2: at this point, m_x[i]'s values are 100.0,100.0 - their original values before I assigned test to m_x[i]!
基本上,由于我将old赋值给m_oldx数组,m_x[I]的值被重置为它的原始值!它不再等于我之前分配给它的测试变量
这肯定不对吧?但这正是发生在我身上的事情。我应该再说一遍,我在这里使用的是GWT——也就是说,这段代码由Google的编译器编译成Javascript。这是java的常规行为还是GWT做错了什么?谢谢你的帮助……让我毛骨悚然:(看来
m_x
和m_oldx
实际上是同一个数组,因此修改一个变量也会修改另一个变量。您可能在前面做过这件事:
m_oldx = m_x;
由于Java的对象引用语义doingm_oldx=m_x
不会复制数组,因此它只是将m_oldx
设置为指向与m_x
相同的数组。如果要复制它,需要显式执行以下操作:
m_oldx = Arrays.copyOf(m_x, m_x.length);
似乎
m_x
和m_oldx
实际上是同一个数组,因此修改一个变量也会修改另一个变量。您可能在前面做过这样的操作:
m_oldx = m_x;
由于Java的对象引用语义doingm_oldx=m_x
不会复制数组,因此它只是将m_oldx
设置为指向与m_x
相同的数组。如果要复制它,需要显式执行以下操作:
m_oldx = Arrays.copyOf(m_x, m_x.length);
当出现这样的问题时,我的第一个想法是m_x和m_oldx在某个点上被设置为相等,因为Java通过值而不是通过创建副本将实例传递给变量。例如,如果在任何点上:
m_oldx = m_x;
或
这会导致这个问题。当出现类似问题时,我的第一个想法是m_x和m_oldx在某个点上被设置为彼此相等,因为Java通过值而不是通过创建副本将实例传递给变量。例如,如果在任何点上:
m_oldx = m_x;
或
这可能会导致这个问题。我怀疑这里发生了其他事情。你能在这里发布一个简短的测试用例来显示这个行为吗?还有,包含此数据的类是否被多个线程使用?你能给我们创建m_x和m_oldx的代码吗?我怀疑这里发生了其他事情。你能在这里发布一个简短的测试用例吗为了显示行为?还有,其中包含此数据的类是否被多个线程使用?能否给我们创建m_x和m_oldx的代码?arrrgghhh…您是正确的。我已将这两个设置为引用另一个数组,每个数组引用相同的数组。我显然需要修改我的Java引用逻辑!非常感谢,我可能已经我整晚都在讨论这个问题。虽然你的意思可能是正确的,但你的回答中有很多问题需要反对:Java没有指针,但是引用和命名它们指针可能会让人困惑,甚至可能让其他人认为你可以用它们做指针算术。此外,Java只有一种传递对象(实例)的方法:通过值(引用是按值复制的!)将其称为“按指针传递”,这是误导(甚至是错误的)。你当然是对的。我在回答中使用了一些不好的术语。它已被相应地更正。arrrgggghh…你是对的。我已将这两个设置为引用另一个数组,每个数组引用相同的数组。我显然需要修改我的Java引用逻辑!非常感谢,否则我可能整晚都在这样做。而你可能y的意思是正确的,在你的答案中有很多东西需要反对:Java没有指针,但引用和命名它们可能会让人困惑,甚至可能让其他人认为你可以用它们做指针算术。此外,Java只有一种传递对象(实例)的方法:按值(引用按值复制!),调用它“通过指针传递”是误导性的(甚至是错误的)。你当然是正确的。我在回答中使用了一些不好的术语。它已被相应地更正。