Java 使用新对象也会更改引用

Java 使用新对象也会更改引用,java,reference,libgdx,Java,Reference,Libgdx,我有一个对象列表,其中包含一个我(想要)用作参考的数组。因此,当我创建一个新对象时,用列表中的数组填充它,然后开始更改新对象。我不希望列表中对象的初始数组发生更改 我基本上是这样做的: //Fill list with my reference objects; Object newObject = new Object(); //So i do not change the previous newObject in the loop. newObject = (find)ObjectFro

我有一个对象列表,其中包含一个我(想要)用作参考的数组。因此,当我创建一个新对象时,用列表中的数组填充它,然后开始更改新对象。我不希望列表中对象的初始数组发生更改

我基本上是这样做的:

//Fill list with my reference objects;

Object newObject = new Object(); //So i do not change the previous newObject in the loop.
newObject = (find)ObjectFromList;
newObject.array = RotateArray(newObject.array);
如果我用列表中的相同对象填充另一个新对象,则该对象已旋转。我希望我已经说得够清楚了。下面是我的代码的简化版本,仍然有点凌乱:

装载室()//将文件中的所有对象和数组加载到列表中

for(int x=0;x<width;x++)
        {
            for(int y=0;y<height;y++)
            {
                Room newRoom = new Room();
                //Fill newroom with correct room type, rotate and build tilemap.
                //Dead ends
                if(!mazeMap[x][y].N && !mazeMap[x][y].E && mazeMap[x][y].S && !mazeMap[x][y].W)
                {
                    newRoom = FindRoom(Room.RoomType.DeadEnd);
                    newRoom.room = TurnRoomCW(newRoom.room);
                    newRoom.room = TurnRoomCW(newRoom.room);
                    newRoom.room = TurnRoomCW(newRoom.room);
                }
                else if(!mazeMap[x][y].N && mazeMap[x][y].E && !mazeMap[x][y].S && !mazeMap[x][y].W)
                {
                    newRoom = FindRoom(Room.RoomType.DeadEnd);
                }
                            //Etc, etc then i build a map from the newRoom.room array        
    }
}

当我想把一个角落类型的房间,说东北到正确的位置,所有其他房间都会跟着它转。因此,当我想将SW转换为位置时,NE的位置将再次出错。

基本上,Java对象是引用(如果您愿意,是指针),因此除非您对数组(或任何其他对象)进行显式复制,否则它将指向同一个对象

如果要避免这种情况,必须先进行克隆:

List myList = referenceList.clone();

无论如何,这通常是一个好习惯,以避免外部世界修改“内部”对象。

您的
FindRoom
方法返回对实际房间的引用。 “TurnRoomCW”返回一个新对象,但随后将该新对象分配回原始房间

所以你的问题就在这里:

newRoom = FindRoom(Room.RoomType.DeadEnd); // 1) find a DeadEnd room
newRoom.room = TurnRoomCW(newRoom.room); // 2) create rotated room, assign it to the room from step 1)
如果要使用新的
房间
对象,则需要以某种方式创建一个新对象。例如,您可以为
Room
定义一个构造函数,该构造函数返回从现有对象初始化的新对象。比如说,

/** copy constructor */
public Room(Room oldRoom) { 
   this(); // regular constructor
   this.room = oldRoom.room.clone(); // new Room gets its own array!
   this.roomType = oldRoom.roomType;
   // … etc for any other member variables
}

不,对不起,你说得不够清楚。一个简单的问题说明,没有多余的代码将是一个更好的开始。我会试试。但原因是:inti=10;int j=i;j-1;现在我还是10岁,j是9岁。我在我的代码中也做了同样的事情。我没有克隆方法的访问权限。我正在使用ArrayList。ArrayList是可克隆的()。另一个选项类似于:newList=newarraylist(referenceList);
newRoom = FindRoom(Room.RoomType.DeadEnd); // 1) find a DeadEnd room
newRoom.room = TurnRoomCW(newRoom.room); // 2) create rotated room, assign it to the room from step 1)
/** copy constructor */
public Room(Room oldRoom) { 
   this(); // regular constructor
   this.room = oldRoom.room.clone(); // new Room gets its own array!
   this.roomType = oldRoom.roomType;
   // … etc for any other member variables
}