Java新手:如何在不建立引用的情况下将对象的当前状态分配给另一个?

时间:2021-08-10 16:57:01

Once again, I'm looking for a way to bypass this array problem, how? Is there any way other than clone()? I'm asking because fighting with clone(), protection and implemention stuff didn't work for me...

再一次,我正在寻找绕过这个阵列问题的方法,怎么样?除了clone()之外还有什么方法吗?我问,因为与克隆(),保护和实施的斗争对我来说不起作用......

//assuming you have proper class and constructor (point(int x, int y))    
/*
   point 7POINTSARRAY[]=new point[7];
   for(int i=0;i<7;i++)
   {
   7POINTSARRAY[i].x=i;
   7POINTSARRAY[i].y=i;
   }
//This won't work, so...
 */

point B = new point(0,0); // You need this.
for(int i=0;i<7;i++){
    7POINTSARRAY[i]=B;     // And this. 
    //But I want to read and assign value only,
    //  not establish a reference, so it can work How?
    7POINTSARRAY[i].x=i;
    7POINTSARRAY[i].y=i;
    System.out.println(7POINTSARRAY[i].x);
}
System.out.println(7POINTSARRAY[1].x); 

Though desired output is A[1].x=1, it's been owerwritten several times, and now A[1].x = 7.

虽然期望的输出是A [1] .x = 1,但它已被多次写入,现在A [1] .x = 7。

3 个解决方案

#1


2  

You need to a create a new point for every element of the array if you want them all to reference different objects:

如果希望所有元素都引用不同的对象,则需要为数组的每个元素创建一个新点:

    for(int i=0;i<7;i++)
    {
        point B = new point(0,0); // Put this *inside* the loop
        7POINTSARRAY[i]=B;        // Now B is a new instance of point
        7POINTSARRAY[i].x=i;
        7POINTSARRAY[i].y=i;
        System.out.println(7POINTSARRAY[i].x);
    }
    System.out.println(7POINTSARRAY[1].x); // should now print 1

I haven't changed your code formatting but improving that will make the above clearer and easier to understand.

我没有改变你的代码格式,但改进它将使上面更清晰,更容易理解。

#2


0  

Sorry but Java works only with references for complex objects. You should use and implement clone() correctly this can't be the problem. clone() is well defined approach.

抱歉,Java只适用于复杂对象的引用。你应该正确使用和实现clone()这不是问题。 clone()是定义良好的方法。

Typical clone for first level class looks like following

第一级课程的典型克隆如下所示

    @Override
    public Object clone() {
        try {
            A ans = (A) super.clone();

            // do complex stuff

            return ans;

        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }

    }

the line

A ans = (A) super.clone();

does default clone, which includes cloning object but not it's members. You should cascade clone for members. Since clone() is a member, it has access to protected members of the parent.

默认克隆,包括克隆对象,但不包括它的成员。您应该为成员级联克隆。由于clone()是成员,因此它可以访问父项的受保护成员。

If your parent is Cloneable you should write

如果你的父母是克隆人你应该写

    @Override
    public Object clone() {
        A ans = (A) super.clone();

        // do complex stuff

        return ans;
    }

because parent can't throw exception.

因为父母不能抛出异常。

For example, if you have point class looking like follows

例如,如果您的点类看起来如下

class point {
   public point(double x, double y) { this.x = x; this.y = y; }
   public double x;
   public double y;
}

then you should just fix it in the following way

那么你应该按照以下方式修复它

class point implements Cloneable {
   public point(double x, double y) { this.x = x; this.y = y; }
   public double x;
   public double y;
}

to make it cloneable.

使它可以克隆

Then you will be able to write

然后你就可以写了

point a = new point(1,2);
point b = (point) a.clone();

and you will get 2 separate copies.

你将获得2份单独的副本。

#3


0  

the problem is with the line

问题在于线

7POINTSARRAY[i]=B

which means that each object in 7POINTSARRAY refer (or points) to the same object B.

这意味着7POINTSARRAY中的每个对象都引用(或指向)同一个对象B.

so when you do inside the loop

所以当你在循环中做

7POINTSARRAY[i].x=i;
            7POINTSARRAY[i].y=i;

you actually always changing B.

你实际上总是在改变B.

You should do instead:

你应该这样做:

for(int i=0;i<7;i++){
    7POINTSARRAY[i] = new point(i,i);
}

#1


2  

You need to a create a new point for every element of the array if you want them all to reference different objects:

如果希望所有元素都引用不同的对象,则需要为数组的每个元素创建一个新点:

    for(int i=0;i<7;i++)
    {
        point B = new point(0,0); // Put this *inside* the loop
        7POINTSARRAY[i]=B;        // Now B is a new instance of point
        7POINTSARRAY[i].x=i;
        7POINTSARRAY[i].y=i;
        System.out.println(7POINTSARRAY[i].x);
    }
    System.out.println(7POINTSARRAY[1].x); // should now print 1

I haven't changed your code formatting but improving that will make the above clearer and easier to understand.

我没有改变你的代码格式,但改进它将使上面更清晰,更容易理解。

#2


0  

Sorry but Java works only with references for complex objects. You should use and implement clone() correctly this can't be the problem. clone() is well defined approach.

抱歉,Java只适用于复杂对象的引用。你应该正确使用和实现clone()这不是问题。 clone()是定义良好的方法。

Typical clone for first level class looks like following

第一级课程的典型克隆如下所示

    @Override
    public Object clone() {
        try {
            A ans = (A) super.clone();

            // do complex stuff

            return ans;

        } catch (CloneNotSupportedException e) {
            throw new AssertionError();
        }

    }

the line

A ans = (A) super.clone();

does default clone, which includes cloning object but not it's members. You should cascade clone for members. Since clone() is a member, it has access to protected members of the parent.

默认克隆,包括克隆对象,但不包括它的成员。您应该为成员级联克隆。由于clone()是成员,因此它可以访问父项的受保护成员。

If your parent is Cloneable you should write

如果你的父母是克隆人你应该写

    @Override
    public Object clone() {
        A ans = (A) super.clone();

        // do complex stuff

        return ans;
    }

because parent can't throw exception.

因为父母不能抛出异常。

For example, if you have point class looking like follows

例如,如果您的点类看起来如下

class point {
   public point(double x, double y) { this.x = x; this.y = y; }
   public double x;
   public double y;
}

then you should just fix it in the following way

那么你应该按照以下方式修复它

class point implements Cloneable {
   public point(double x, double y) { this.x = x; this.y = y; }
   public double x;
   public double y;
}

to make it cloneable.

使它可以克隆

Then you will be able to write

然后你就可以写了

point a = new point(1,2);
point b = (point) a.clone();

and you will get 2 separate copies.

你将获得2份单独的副本。

#3


0  

the problem is with the line

问题在于线

7POINTSARRAY[i]=B

which means that each object in 7POINTSARRAY refer (or points) to the same object B.

这意味着7POINTSARRAY中的每个对象都引用(或指向)同一个对象B.

so when you do inside the loop

所以当你在循环中做

7POINTSARRAY[i].x=i;
            7POINTSARRAY[i].y=i;

you actually always changing B.

你实际上总是在改变B.

You should do instead:

你应该这样做:

for(int i=0;i<7;i++){
    7POINTSARRAY[i] = new point(i,i);
}