简体   繁体   English

如何在不访问私有变量的情况下创建实例的副本

[英]How to create a copy of an instance without having access to private variables

Im having a bit of a problem. 我有一个问题。 Let me show you the code first: 让我先向您展示代码:

public class Direction {
    private CircularList xSpeed, zSpeed;
    private int[] dirSquare = {-1, 0, 1, 0};

public Direction(int xSpeed, int zSpeed){
    this.xSpeed = new CircularList(dirSquare, xSpeed);
    this.zSpeed = new CircularList(dirSquare, zSpeed);
}
public Direction(Point dirs){
    this(dirs.x, dirs.y);
}
public void shiftLeft(){
    xSpeed.shiftLeft();
    zSpeed.shiftRight();
}
public void shiftRight(){
    xSpeed.shiftRight();
    zSpeed.shiftLeft();
}
public int getXSpeed(){
    return this.xSpeed.currentValue();
}
public int getZSpeed(){
    return this.zSpeed.currentValue();
}
}

Now lets say i have an instance of Direction: 现在说我有一个Direction的实例:

Direction dir = new Direction(0, 0);

As you can see in the code of Direction, the arguments fed to the constructor, are passed directly to some other class. 如您在Directional的代码中所见,馈给构造函数的参数被直接传递给其他一些类。 One cannot be sure if they stay the same because methods shiftRight() and shiftLeft could have been called, which changes thos numbers. 不能确定它们是否保持不变,因为可能已经调用了shiftRight()和shiftLeft方法,从而改变了数值。

My question is, how do i create a completely new instance of Direction, that is basically copy(not by reference) of dir? 我的问题是,我如何创建Direction的全新实例,该实例基本上是dir的副本(不是通过引用)?

The only way i see it, is to create public methods in both CircularList and Direction that return the variables needed to create a copy of the instance, but this solution seems really dirty since those numbers are not supposed to be touched after beeing fed to the constructor, and therefore they are private. 我看到它的唯一方法是在CircularList和Direction中都创建公共方法,这些方法返回创建实例副本所需的变量,但是此解决方案似乎真的很脏,因为不应将这些数字在喂给蜜蜂之后再进行触摸。构造函数,因此它们是私有的。

EDIT1: 编辑1:

CircularList is a class that is a looped around version of ArrayList. CircularList是一个在ArrayList版本周围循环的类。 You can see that i feed it an array called dirSquare and then a number. 您可以看到我将名为dirSquare的数组输入一个数字。 The number is an index in that array. 该数字是该数组中的索引。 So if the number i feed it is for example 3, it will be the last element in dirSquare, which has value of 0. When i use shiftRight and shiftLeft, the index gets incremented/decremented and if i increment pass the size of the last element of the array, it loops around and starts with 0th elemnt. 因此,如果我输入的数字例如为3,它将是dirSquare中的最后一个元素,其值为0。当我使用shiftRight和shiftLeft时,索引将递增/递减,并且如果我递增则通过最后一个的大小数组的元素,它循环并从第0个元素开始。 The same thing happens if i go pass 0 on the other side. 如果我在另一侧传递0,也会发生同样的事情。 Thats why its called Circular list. 这就是为什么将其称为通函列表。 I cant use getXSpeed/getZSpeed because they return the value of the array. 我不能使用getXSpeed / getZSpeed,因为它们返回数组的值。 I need the index, which is strictly an implementation variable. 我需要索引,严格来说这是一个实现变量。

Why not add another constructor taking a Direction parameter. 为什么不添加另一个带有Direction参数的构造函数。 Something like: 就像是:

public Direction(Direction source) {
    this(source.xSpeed, source.ZSpeed);
}

A common way to go about this, is to create a copy constructor. 解决此问题的常用方法是创建一个副本构造函数。 An example can be found here 可以在这里找到一个例子

Another solution would be to implement the Cloneable interface, but most developers recommend against it, including Joshua Bloch in Effective Java , calling Java's clone " deeply broken ". 另一个解决方案是实现Cloneable接口,但是大多数开发人员都建议不要使用它,包括Effective Java中的 Joshua Bloch,称Java的clone严重破坏 ”。

I'd add a private/protected constructor without arguments, so you can initialize each member with its own copy (with your constructor it seems you'll have a reference inside your CircularLists, so you need to inizialize them manually inside clone method). 我将添加一个不带参数的私有/受保护的构造函数,因此您可以使用其自己的副本来初始化每个成员(使用构造函数,您似乎在CircularList中有一个引用,因此您需要在clone方法中手动初始化它们)。

Edited 已编辑

public Direction() {};

public Direction Clone() {
    Direction dir = new Direction();
    dir.diSquare=this.dirSquare;

    for each elem in xSpeed
        dir.xSpeed.Add(elem)

    for each elem in zSpeed
        dir.zSpeed.Add(elem)

    return dir;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM